home *** CD-ROM | disk | FTP | other *** search
/ Libris Britannia 4 / science library(b).zip / science library(b) / DJGPP / GCC257S5.ZIP / src / gcc-257 / md < prev    next >
Text File  |  1993-12-15  |  142KB  |  5,262 lines

  1. ;; GCC machine description for Intel 80386.
  2. ;; Copyright (C) 1988 Free Software Foundation, Inc.
  3. ;; Mostly by William Schelter.
  4.  
  5. ;; This file is part of GNU CC.
  6.  
  7. ;; GNU CC is free software; you can redistribute it and/or modify
  8. ;; it under the terms of the GNU General Public License as published by
  9. ;; the Free Software Foundation; either version 2, or (at your option)
  10. ;; any later version.
  11.  
  12. ;; GNU CC is distributed in the hope that it will be useful,
  13. ;; but WITHOUT ANY WARRANTY; without even the implied warranty of
  14. ;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
  15. ;; GNU General Public License for more details.
  16.  
  17. ;; You should have received a copy of the GNU General Public License
  18. ;; along with GNU CC; see the file COPYING.  If not, write to
  19. ;; the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA.
  20.  
  21.  
  22. ;; The original PO technology requires these to be ordered by speed,
  23. ;; so that assigner will pick the fastest.
  24.  
  25. ;; See file "rtl.def" for documentation on define_insn, match_*, et. al.
  26.  
  27. ;; Macro #define NOTICE_UPDATE_CC in file i386.h handles condition code
  28. ;; updates for most instructions.
  29.  
  30. ;; Macro REG_CLASS_FROM_LETTER in file i386.h defines the register
  31. ;; constraint letters.
  32.  
  33. ;; the special asm out single letter directives following a '%' are:
  34. ;; 'z' mov%z1 would be movl, movw, or movb depending on the mode of
  35. ;;     operands[1].
  36. ;; 'L' Print the opcode suffix for a 32-bit integer opcode.
  37. ;; 'W' Print the opcode suffix for a 16-bit integer opcode.
  38. ;; 'B' Print the opcode suffix for an 8-bit integer opcode.
  39. ;; 'S' Print the opcode suffix for a 32-bit float opcode.
  40. ;; 'Q' Print the opcode suffix for a 64-bit float opcode.
  41.  
  42. ;; 'b' Print the QImode name of the register for the indicated operand.
  43. ;;     %b0 would print %al if operands[0] is reg 0.
  44. ;; 'w' Likewise, print the HImode name of the register.
  45. ;; 'k' Likewise, print the SImode name of the register.
  46. ;; 'h' Print the QImode name for a "high" register, either ah, bh, ch or dh.
  47. ;; 'y' Print "st(0)" instead of "st" as a register.
  48. ;; 'T' Print the opcode suffix for an 80-bit extended real XFmode float opcode.
  49.  
  50. ;; UNSPEC usage:
  51. ;; 0  This is a `scas' operation.  The mode of the UNSPEC is always SImode.
  52. ;;    operand 0 is the memory address to scan.
  53. ;;    operand 1 is a register containing the value to scan for.  The mode
  54. ;;       of the scas opcode will be the same as the mode of this operand.
  55. ;;    operand 2 is the known alignment of operand 0.
  56. ;; 1  This is a `sin' operation.  The mode of the UNSPEC is MODE_FLOAT.
  57. ;;    operand 0 is the argument for `sin'.
  58. ;; 2  This is a `cos' operation.  The mode of the UNSPEC is MODE_FLOAT.
  59. ;;    operand 0 is the argument for `cos'.
  60.  
  61. ;; "movl MEM,REG / testl REG,REG" is faster on a 486 than "cmpl $0,MEM".
  62. ;; But restricting MEM here would mean that gcc could not remove a redundant
  63. ;; test in cases like "incl MEM / je TARGET".
  64. ;;
  65. ;; We don't want to allow a constant operand for test insns because
  66. ;; (set (cc0) (const_int foo)) has no mode information.  Such insns will
  67. ;; be folded while optimizing anyway.
  68.  
  69. ;; All test insns have expanders that save the operands away without
  70. ;; actually generating RTL.  The bCOND or sCOND (emitted immediately
  71. ;; after the tstM or cmp) will actually emit the tstM or cmpM.
  72.  
  73. (define_insn "tstsi_1"
  74.   [(set (cc0)
  75.     (match_operand:SI 0 "nonimmediate_operand" "rm"))]
  76.   ""
  77.   "*
  78. {
  79.   if (REG_P (operands[0]))
  80.     return AS2 (test%L0,%0,%0);
  81.  
  82.   operands[1] = const0_rtx;
  83.   return AS2 (cmp%L0,%1,%0);
  84. }")
  85.  
  86. (define_expand "tstsi"
  87.   [(set (cc0)
  88.     (match_operand:SI 0 "nonimmediate_operand" ""))]
  89.   ""
  90.   "
  91. {
  92.   i386_compare_gen = gen_tstsi_1;
  93.   i386_compare_op0 = operands[0];
  94.   DONE;
  95. }")
  96.  
  97. (define_insn "tsthi_1"
  98.   [(set (cc0)
  99.     (match_operand:HI 0 "nonimmediate_operand" "rm"))]
  100.   ""
  101.   "*
  102. {
  103.   if (REG_P (operands[0]))
  104.     return AS2 (test%W0,%0,%0);
  105.  
  106.   operands[1] = const0_rtx;
  107.   return AS2 (cmp%W0,%1,%0);
  108. }")
  109.  
  110. (define_expand "tsthi"
  111.   [(set (cc0)
  112.     (match_operand:HI 0 "nonimmediate_operand" ""))]
  113.   ""
  114.   "
  115. {
  116.   i386_compare_gen = gen_tsthi_1;
  117.   i386_compare_op0 = operands[0];
  118.   DONE;
  119. }")
  120.  
  121. (define_insn "tstqi_1"
  122.   [(set (cc0)
  123.     (match_operand:QI 0 "nonimmediate_operand" "qm"))]
  124.   ""
  125.   "*
  126. {
  127.   if (REG_P (operands[0]))
  128.     return AS2 (test%B0,%0,%0);
  129.  
  130.   operands[1] = const0_rtx;
  131.   return AS2 (cmp%B0,%1,%0);
  132. }")
  133.  
  134. (define_expand "tstqi"
  135.   [(set (cc0)
  136.     (match_operand:QI 0 "nonimmediate_operand" ""))]
  137.   ""
  138.   "
  139. {
  140.   i386_compare_gen = gen_tstqi_1;
  141.   i386_compare_op0 = operands[0];
  142.   DONE;
  143. }")
  144.  
  145. (define_insn "tstsf_cc"
  146.   [(set (cc0)
  147.     (match_operand:SF 0 "register_operand" "f"))
  148.    (clobber (match_scratch:HI 1 "=a"))]
  149.   "TARGET_80387 && ! TARGET_IEEE_FP"
  150.   "*
  151. {
  152.   if (! STACK_TOP_P (operands[0]))
  153.     abort ();
  154.  
  155.   output_asm_insn (\"ftst\", operands);
  156.  
  157.   if (find_regno_note (insn, REG_DEAD, FIRST_STACK_REG))
  158.     output_asm_insn (AS1 (fstp,%y0), operands);
  159.  
  160.   return (char *) output_fp_cc0_set (insn);
  161. }")
  162.  
  163. ;; Don't generate tstsf if generating IEEE code, since the `ftst' opcode
  164. ;; isn't IEEE compliant.
  165.  
  166. (define_expand "tstsf"
  167.   [(parallel [(set (cc0)
  168.            (match_operand:SF 0 "register_operand" ""))
  169.           (clobber (match_scratch:HI 1 ""))])]
  170.   "TARGET_80387 && ! TARGET_IEEE_FP"
  171.   "
  172. {
  173.   i386_compare_gen = gen_tstsf_cc;
  174.   i386_compare_op0 = operands[0];
  175.   DONE;
  176. }")
  177.  
  178. (define_insn "tstdf_cc"
  179.   [(set (cc0)
  180.     (match_operand:DF 0 "register_operand" "f"))
  181.    (clobber (match_scratch:HI 1 "=a"))]
  182.   "TARGET_80387 && ! TARGET_IEEE_FP"
  183.   "*
  184. {
  185.   if (! STACK_TOP_P (operands[0]))
  186.     abort ();
  187.  
  188.   output_asm_insn (\"ftst\", operands);
  189.  
  190.   if (find_regno_note (insn, REG_DEAD, FIRST_STACK_REG))
  191.     output_asm_insn (AS1 (fstp,%y0), operands);
  192.  
  193.   return (char *) output_fp_cc0_set (insn);
  194. }")
  195.  
  196. ;; Don't generate tstdf if generating IEEE code, since the `ftst' opcode
  197. ;; isn't IEEE compliant.
  198.  
  199. (define_expand "tstdf"
  200.   [(parallel [(set (cc0)
  201.            (match_operand:DF 0 "register_operand" ""))
  202.           (clobber (match_scratch:HI 1 ""))])]
  203.   "TARGET_80387 && ! TARGET_IEEE_FP"
  204.   "
  205. {
  206.   i386_compare_gen = gen_tstdf_cc;
  207.   i386_compare_op0 = operands[0];
  208.   DONE;
  209. }")
  210.  
  211. (define_insn "tstxf_cc"
  212.   [(set (cc0)
  213.     (match_operand:XF 0 "register_operand" "f"))
  214.    (clobber (match_scratch:HI 1 "=a"))]
  215.   "TARGET_80387 && ! TARGET_IEEE_FP"
  216.   "*
  217. {
  218.   if (! STACK_TOP_P (operands[0]))
  219.     abort ();
  220.  
  221.   output_asm_insn (\"ftst\", operands);
  222.  
  223.   if (find_regno_note (insn, REG_DEAD, FIRST_STACK_REG))
  224.     output_asm_insn (AS1 (fstp,%y0), operands);
  225.  
  226.   return (char *) output_fp_cc0_set (insn);
  227. }")
  228.  
  229. ;; Don't generate tstdf if generating IEEE code, since the `ftst' opcode
  230. ;; isn't IEEE compliant.
  231.  
  232. (define_expand "tstxf"
  233.   [(parallel [(set (cc0)
  234.            (match_operand:XF 0 "register_operand" ""))
  235.           (clobber (match_scratch:HI 1 ""))])]
  236.   "TARGET_80387 && ! TARGET_IEEE_FP"
  237.   "
  238. {
  239.   i386_compare_gen = gen_tstxf_cc;
  240.   i386_compare_op0 = operands[0];
  241.   DONE;
  242. }")
  243.  
  244. ;;- compare instructions.  See comments above tstM patterns about
  245. ;;  expansion of these insns.
  246.  
  247. (define_insn "cmpsi_1"
  248.   [(set (cc0)
  249.     (compare (match_operand:SI 0 "nonimmediate_operand" "mr,r")
  250.          (match_operand:SI 1 "general_operand" "ri,mr")))]
  251.   "GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM"
  252.   "*
  253. {
  254.   if (CONSTANT_P (operands[0]) || GET_CODE (operands[1]) == MEM)
  255.     {
  256.       cc_status.flags |= CC_REVERSED;
  257.       return AS2 (cmp%L0,%0,%1);
  258.     }
  259.   return AS2 (cmp%L0,%1,%0);
  260. }")
  261.  
  262. (define_expand "cmpsi"
  263.   [(set (cc0)
  264.     (compare (match_operand:SI 0 "nonimmediate_operand" "")
  265.          (match_operand:SI 1 "general_operand" "")))]
  266.   ""
  267.   "
  268. {
  269.   if (GET_CODE (operands[0]) == MEM && GET_CODE (operands[1]) == MEM)
  270.     operands[0] = force_reg (SImode, operands[0]);
  271.  
  272.   i386_compare_gen = gen_cmpsi_1;
  273.   i386_compare_op0 = operands[0];
  274.   i386_compare_op1 = operands[1];
  275.   DONE;
  276. }")
  277.  
  278. (define_insn "cmphi_1"
  279.   [(set (cc0)
  280.     (compare (match_operand:HI 0 "nonimmediate_operand" "mr,r")
  281.          (match_operand:HI 1 "general_operand" "ri,mr")))]
  282.   "GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM"
  283.   "*
  284. {
  285.   if (CONSTANT_P (operands[0]) || GET_CODE (operands[1]) == MEM)
  286.     {
  287.       cc_status.flags |= CC_REVERSED;
  288.       return AS2 (cmp%W0,%0,%1);
  289.     }
  290.   return AS2 (cmp%W0,%1,%0);
  291. }")
  292.  
  293. (define_expand "cmphi"
  294.   [(set (cc0)
  295.     (compare (match_operand:HI 0 "nonimmediate_operand" "")
  296.          (match_operand:HI 1 "general_operand" "")))]
  297.   ""
  298.   "
  299. {
  300.   if (GET_CODE (operands[0]) == MEM && GET_CODE (operands[1]) == MEM)
  301.     operands[0] = force_reg (HImode, operands[0]);
  302.  
  303.   i386_compare_gen = gen_cmphi_1;
  304.   i386_compare_op0 = operands[0];
  305.   i386_compare_op1 = operands[1];
  306.   DONE;
  307. }")
  308.  
  309. (define_insn "cmpqi_1"
  310.   [(set (cc0)
  311.     (compare (match_operand:QI 0 "nonimmediate_operand" "q,mq")
  312.          (match_operand:QI 1 "general_operand" "qm,nq")))]
  313.   "GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM"
  314.   "*
  315. {
  316.   if (CONSTANT_P (operands[0]) || GET_CODE (operands[1]) == MEM)
  317.     {
  318.       cc_status.flags |= CC_REVERSED;
  319.       return AS2 (cmp%B0,%0,%1);
  320.     }
  321.   return AS2 (cmp%B0,%1,%0);
  322. }")
  323.  
  324. (define_expand "cmpqi"
  325.   [(set (cc0)
  326.     (compare (match_operand:QI 0 "nonimmediate_operand" "")
  327.          (match_operand:QI 1 "general_operand" "")))]
  328.   ""
  329.   "
  330. {
  331.   if (GET_CODE (operands[0]) == MEM && GET_CODE (operands[1]) == MEM)
  332.     operands[0] = force_reg (QImode, operands[0]);
  333.  
  334.   i386_compare_gen = gen_cmpqi_1;
  335.   i386_compare_op0 = operands[0];
  336.   i386_compare_op1 = operands[1];
  337.   DONE;
  338. }")
  339.  
  340. ;; These implement float point compares.  For each of DFmode and
  341. ;; SFmode, there is the normal insn, and an insn where the second operand
  342. ;; is converted to the desired mode.
  343.  
  344. (define_insn ""
  345.   [(set (cc0)
  346.     (match_operator 2 "VOIDmode_compare_op"
  347.             [(match_operand:XF 0 "nonimmediate_operand" "f")
  348.              (match_operand:XF 1 "nonimmediate_operand" "f")]))
  349.    (clobber (match_scratch:HI 3 "=a"))]
  350.   "TARGET_80387
  351.    && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
  352.   "* return (char *) output_float_compare (insn, operands);")
  353.  
  354. (define_insn ""
  355.   [(set (cc0)
  356.     (match_operator 2 "VOIDmode_compare_op"
  357.             [(match_operand:XF 0 "register_operand" "f")
  358.              (float:XF
  359.               (match_operand:SI 1 "nonimmediate_operand" "rm"))]))
  360.    (clobber (match_scratch:HI 3 "=a"))]
  361.   "TARGET_80387"
  362.   "* return (char *) output_float_compare (insn, operands);")
  363.  
  364. (define_insn ""
  365.   [(set (cc0)
  366.     (match_operator 2 "VOIDmode_compare_op"
  367.             [(float:XF
  368.               (match_operand:SI 0 "nonimmediate_operand" "rm"))
  369.              (match_operand:XF 1 "register_operand" "f")]))
  370.    (clobber (match_scratch:HI 3 "=a"))]
  371.   "TARGET_80387"
  372.   "* return (char *) output_float_compare (insn, operands);")
  373.  
  374. (define_insn ""
  375.   [(set (cc0)
  376.     (match_operator 2 "VOIDmode_compare_op"
  377.             [(match_operand:XF 0 "register_operand" "f")
  378.              (float_extend:XF
  379.               (match_operand:DF 1 "nonimmediate_operand" "fm"))]))
  380.    (clobber (match_scratch:HI 3 "=a"))]
  381.   "TARGET_80387"
  382.   "* return (char *) output_float_compare (insn, operands);")
  383.  
  384. (define_insn ""
  385.   [(set (cc0)
  386.     (match_operator 2 "VOIDmode_compare_op"
  387.             [(match_operand:XF 0 "register_operand" "f")
  388.              (float_extend:XF
  389.               (match_operand:SF 1 "nonimmediate_operand" "fm"))]))
  390.    (clobber (match_scratch:HI 3 "=a"))]
  391.   "TARGET_80387"
  392.   "* return (char *) output_float_compare (insn, operands);")
  393.  
  394. (define_insn ""
  395.   [(set (cc0)
  396.     (compare:CCFPEQ (match_operand:XF 0 "register_operand" "f")
  397.             (match_operand:XF 1 "register_operand" "f")))
  398.    (clobber (match_scratch:HI 2 "=a"))]
  399.   "TARGET_80387"
  400.   "* return (char *) output_float_compare (insn, operands);")
  401.  
  402. (define_insn ""
  403.   [(set (cc0)
  404.     (match_operator 2 "VOIDmode_compare_op"
  405.             [(match_operand:DF 0 "nonimmediate_operand" "f,fm")
  406.              (match_operand:DF 1 "nonimmediate_operand" "fm,f")]))
  407.    (clobber (match_scratch:HI 3 "=a,a"))]
  408.   "TARGET_80387
  409.    && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
  410.   "* return (char *) output_float_compare (insn, operands);")
  411.  
  412. (define_insn ""
  413.   [(set (cc0)
  414.     (match_operator 2 "VOIDmode_compare_op"
  415.             [(match_operand:DF 0 "register_operand" "f")
  416.              (float:DF
  417.               (match_operand:SI 1 "nonimmediate_operand" "rm"))]))
  418.    (clobber (match_scratch:HI 3 "=a"))]
  419.   "TARGET_80387"
  420.   "* return (char *) output_float_compare (insn, operands);")
  421.  
  422. (define_insn ""
  423.   [(set (cc0)
  424.     (match_operator 2 "VOIDmode_compare_op"
  425.             [(float:DF
  426.               (match_operand:SI 0 "nonimmediate_operand" "rm"))
  427.              (match_operand:DF 1 "register_operand" "f")]))
  428.    (clobber (match_scratch:HI 3 "=a"))]
  429.   "TARGET_80387"
  430.   "* return (char *) output_float_compare (insn, operands);")
  431.  
  432. (define_insn ""
  433.   [(set (cc0)
  434.     (match_operator 2 "VOIDmode_compare_op"
  435.             [(match_operand:DF 0 "register_operand" "f")
  436.              (float_extend:DF
  437.               (match_operand:SF 1 "nonimmediate_operand" "fm"))]))
  438.    (clobber (match_scratch:HI 3 "=a"))]
  439.   "TARGET_80387"
  440.   "* return (char *) output_float_compare (insn, operands);")
  441.  
  442. (define_insn ""
  443.   [(set (cc0)
  444.     (match_operator 2 "VOIDmode_compare_op"
  445.             [(float_extend:DF
  446.               (match_operand:SF 0 "nonimmediate_operand" "fm"))
  447.              (match_operand:DF 1 "register_operand" "f")]))
  448.    (clobber (match_scratch:HI 3 "=a"))]
  449.   "TARGET_80387"
  450.   "* return (char *) output_float_compare (insn, operands);")
  451.  
  452. (define_insn ""
  453.   [(set (cc0)
  454.     (compare:CCFPEQ (match_operand:DF 0 "register_operand" "f")
  455.             (match_operand:DF 1 "register_operand" "f")))
  456.    (clobber (match_scratch:HI 2 "=a"))]
  457.   "TARGET_80387"
  458.   "* return (char *) output_float_compare (insn, operands);")
  459.  
  460. ;; These two insns will never be generated by combine due to the mode of
  461. ;; the COMPARE.
  462. ;(define_insn ""
  463. ;  [(set (cc0)
  464. ;    (compare:CCFPEQ (match_operand:DF 0 "register_operand" "f")
  465. ;            (float_extend:DF
  466. ;             (match_operand:SF 1 "register_operand" "f"))))
  467. ;   (clobber (match_scratch:HI 2 "=a"))]
  468. ;  "TARGET_80387"
  469. ;  "* return (char *) output_float_compare (insn, operands);")
  470. ;
  471. ;(define_insn ""
  472. ;  [(set (cc0)
  473. ;    (compare:CCFPEQ (float_extend:DF
  474. ;             (match_operand:SF 0 "register_operand" "f"))
  475. ;            (match_operand:DF 1 "register_operand" "f")))
  476. ;   (clobber (match_scratch:HI 2 "=a"))]
  477. ;  "TARGET_80387"
  478. ;  "* return (char *) output_float_compare (insn, operands);")
  479.  
  480. (define_insn "cmpsf_cc_1"
  481.   [(set (cc0)
  482.     (match_operator 2 "VOIDmode_compare_op"
  483.             [(match_operand:SF 0 "nonimmediate_operand" "f,fm")
  484.              (match_operand:SF 1 "nonimmediate_operand" "fm,f")]))
  485.    (clobber (match_scratch:HI 3 "=a,a"))]
  486.   "TARGET_80387
  487.    && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
  488.   "* return (char *) output_float_compare (insn, operands);")
  489.  
  490. (define_insn ""
  491.   [(set (cc0)
  492.     (match_operator 2 "VOIDmode_compare_op"
  493.             [(match_operand:SF 0 "register_operand" "f")
  494.              (float:SF
  495.               (match_operand:SI 1 "nonimmediate_operand" "rm"))]))
  496.    (clobber (match_scratch:HI 3 "=a"))]
  497.   "TARGET_80387"
  498.   "* return (char *) output_float_compare (insn, operands);")
  499.  
  500. (define_insn ""
  501.   [(set (cc0)
  502.     (match_operator 2 "VOIDmode_compare_op"
  503.             [(float:SF
  504.               (match_operand:SI 0 "nonimmediate_operand" "rm"))
  505.              (match_operand:SF 1 "register_operand" "f")]))
  506.    (clobber (match_scratch:HI 3 "=a"))]
  507.   "TARGET_80387"
  508.   "* return (char *) output_float_compare (insn, operands);")
  509.  
  510. (define_insn ""
  511.   [(set (cc0)
  512.     (compare:CCFPEQ (match_operand:SF 0 "register_operand" "f")
  513.             (match_operand:SF 1 "register_operand" "f")))
  514.    (clobber (match_scratch:HI 2 "=a"))]
  515.   "TARGET_80387"
  516.   "* return (char *) output_float_compare (insn, operands);")
  517.  
  518. (define_expand "cmpxf"
  519.   [(set (cc0)
  520.     (compare (match_operand:XF 0 "register_operand" "")
  521.          (match_operand:XF 1 "nonimmediate_operand" "")))]
  522.   "TARGET_80387"
  523.   "
  524. {
  525.   i386_compare_gen = gen_cmpxf_cc;
  526.   i386_compare_gen_eq = gen_cmpxf_ccfpeq;
  527.   i386_compare_op0 = operands[0];
  528.   i386_compare_op1 = operands[1];
  529.   DONE;
  530. }")
  531.  
  532. (define_expand "cmpdf"
  533.   [(set (cc0)
  534.     (compare (match_operand:DF 0 "register_operand" "")
  535.          (match_operand:DF 1 "nonimmediate_operand" "")))]
  536.   "TARGET_80387"
  537.   "
  538. {
  539.   i386_compare_gen = gen_cmpdf_cc;
  540.   i386_compare_gen_eq = gen_cmpdf_ccfpeq;
  541.   i386_compare_op0 = operands[0];
  542.   i386_compare_op1 = operands[1];
  543.   DONE;
  544. }")
  545.  
  546. (define_expand "cmpsf"
  547.   [(set (cc0)
  548.     (compare (match_operand:SF 0 "register_operand" "")
  549.          (match_operand:SF 1 "nonimmediate_operand" "")))]
  550.   "TARGET_80387"
  551.   "
  552. {
  553.   i386_compare_gen = gen_cmpsf_cc;
  554.   i386_compare_gen_eq = gen_cmpsf_ccfpeq;
  555.   i386_compare_op0 = operands[0];
  556.   i386_compare_op1 = operands[1];
  557.   DONE;
  558. }")
  559.  
  560. (define_expand "cmpxf_cc"
  561.   [(parallel [(set (cc0)
  562.            (compare (match_operand:XF 0 "register_operand" "")
  563.                 (match_operand:XF 1 "register_operand" "")))
  564.           (clobber (match_scratch:HI 2 ""))])]
  565.   "TARGET_80387"
  566.   "")
  567.  
  568. (define_expand "cmpxf_ccfpeq"
  569.   [(parallel [(set (cc0)
  570.            (compare:CCFPEQ (match_operand:XF 0 "register_operand" "")
  571.                    (match_operand:XF 1 "register_operand" "")))
  572.           (clobber (match_scratch:HI 2 ""))])]
  573.   "TARGET_80387"
  574.   "
  575. {
  576.   if (! register_operand (operands[1], XFmode))
  577.     operands[1] = copy_to_mode_reg (XFmode, operands[1]);
  578. }")
  579.  
  580. (define_expand "cmpdf_cc"
  581.   [(parallel [(set (cc0)
  582.            (compare (match_operand:DF 0 "register_operand" "")
  583.                 (match_operand:DF 1 "register_operand" "")))
  584.           (clobber (match_scratch:HI 2 ""))])]
  585.   "TARGET_80387"
  586.   "")
  587.  
  588. (define_expand "cmpdf_ccfpeq"
  589.   [(parallel [(set (cc0)
  590.            (compare:CCFPEQ (match_operand:DF 0 "register_operand" "")
  591.                    (match_operand:DF 1 "register_operand" "")))
  592.           (clobber (match_scratch:HI 2 ""))])]
  593.   "TARGET_80387"
  594.   "
  595. {
  596.   if (! register_operand (operands[1], DFmode))
  597.     operands[1] = copy_to_mode_reg (DFmode, operands[1]);
  598. }")
  599.  
  600. (define_expand "cmpsf_cc"
  601.   [(parallel [(set (cc0)
  602.            (compare (match_operand:SF 0 "register_operand" "")
  603.                 (match_operand:SF 1 "register_operand" "")))
  604.           (clobber (match_scratch:HI 2 ""))])]
  605.   "TARGET_80387"
  606.   "")
  607.  
  608. (define_expand "cmpsf_ccfpeq"
  609.   [(parallel [(set (cc0)
  610.            (compare:CCFPEQ (match_operand:SF 0 "register_operand" "")
  611.                    (match_operand:SF 1 "register_operand" "")))
  612.           (clobber (match_scratch:HI 2 ""))])]
  613.   "TARGET_80387"
  614.   "
  615. {
  616.   if (! register_operand (operands[1], SFmode))
  617.     operands[1] = copy_to_mode_reg (SFmode, operands[1]);
  618. }")
  619.  
  620. ;; logical compare
  621.  
  622. (define_insn ""
  623.   [(set (cc0)
  624.     (and:SI (match_operand:SI 0 "general_operand" "%ro")
  625.         (match_operand:SI 1 "general_operand" "ri")))]
  626.   ""
  627.   "*
  628. {
  629.   /* For small integers, we may actually use testb. */
  630.   if (GET_CODE (operands[1]) == CONST_INT
  631.       && ! (GET_CODE (operands[0]) == MEM && MEM_VOLATILE_P (operands[0]))
  632.       && (! REG_P (operands[0]) || QI_REG_P (operands[0])))
  633.     {
  634.       /* We may set the sign bit spuriously.  */
  635.  
  636.       if ((INTVAL (operands[1]) & ~0xff) == 0)
  637.         {
  638.       cc_status.flags |= CC_NOT_NEGATIVE;
  639.       return AS2 (test%B0,%1,%b0);
  640.     }
  641.  
  642.       if ((INTVAL (operands[1]) & ~0xff00) == 0)
  643.         {
  644.       cc_status.flags |= CC_NOT_NEGATIVE;
  645.       operands[1] = GEN_INT (INTVAL (operands[1]) >> 8);
  646.  
  647.       if (QI_REG_P (operands[0]))
  648.         return AS2 (test%B0,%1,%h0);
  649.       else
  650.         {
  651.           operands[0] = adj_offsettable_operand (operands[0], 1);
  652.           return AS2 (test%B0,%1,%b0);
  653.         }
  654.     }
  655.  
  656.       if (GET_CODE (operands[0]) == MEM
  657.       && (INTVAL (operands[1]) & ~0xff0000) == 0)
  658.         {
  659.       cc_status.flags |= CC_NOT_NEGATIVE;
  660.       operands[1] = GEN_INT (INTVAL (operands[1]) >> 16);
  661.       operands[0] = adj_offsettable_operand (operands[0], 2);
  662.       return AS2 (test%B0,%1,%b0);
  663.     }
  664.  
  665.       if (GET_CODE (operands[0]) == MEM
  666.       && (INTVAL (operands[1]) & ~0xff000000) == 0)
  667.         {
  668.       operands[1] = GEN_INT ((INTVAL (operands[1]) >> 24) & 0xff);
  669.       operands[0] = adj_offsettable_operand (operands[0], 3);
  670.       return AS2 (test%B0,%1,%b0);
  671.     }
  672.     }
  673.  
  674.   if (CONSTANT_P (operands[1]) || GET_CODE (operands[0]) == MEM)
  675.     return AS2 (test%L0,%1,%0);
  676.  
  677.   return AS2 (test%L1,%0,%1);
  678. }")
  679.  
  680. (define_insn ""
  681.   [(set (cc0)
  682.     (and:HI (match_operand:HI 0 "general_operand" "%ro")
  683.         (match_operand:HI 1 "general_operand" "ri")))]
  684.   ""
  685.   "*
  686. {
  687.   if (GET_CODE (operands[1]) == CONST_INT
  688.       && ! (GET_CODE (operands[0]) == MEM && MEM_VOLATILE_P (operands[0]))
  689.       && (! REG_P (operands[0]) || QI_REG_P (operands[0])))
  690.     {
  691.       if ((INTVAL (operands[1]) & 0xff00) == 0)
  692.     {
  693.       /* ??? This might not be necessary. */
  694.       if (INTVAL (operands[1]) & 0xffff0000)
  695.         operands[1] = GEN_INT (INTVAL (operands[1]) & 0xff);
  696.  
  697.       /* We may set the sign bit spuriously.  */
  698.       cc_status.flags |= CC_NOT_NEGATIVE;
  699.       return AS2 (test%B0,%1,%b0);
  700.     }
  701.  
  702.       if ((INTVAL (operands[1]) & 0xff) == 0)
  703.         {
  704.       operands[1] = GEN_INT ((INTVAL (operands[1]) >> 8) & 0xff);
  705.  
  706.       if (QI_REG_P (operands[0]))
  707.         return AS2 (test%B0,%1,%h0);
  708.       else
  709.         {
  710.           operands[0] = adj_offsettable_operand (operands[0], 1);
  711.           return AS2 (test%B0,%1,%b0);
  712.         }
  713.     }
  714.     }
  715.  
  716.   if (CONSTANT_P (operands[1]) || GET_CODE (operands[0]) == MEM)
  717.     return AS2 (test%W0,%1,%0);
  718.  
  719.   return AS2 (test%W1,%0,%1);
  720. }")
  721.  
  722. (define_insn ""
  723.   [(set (cc0)
  724.     (and:QI (match_operand:QI 0 "general_operand" "%qm")
  725.         (match_operand:QI 1 "general_operand" "qi")))]
  726.   ""
  727.   "*
  728. {
  729.   if (CONSTANT_P (operands[1]) || GET_CODE (operands[0]) == MEM)
  730.     return AS2 (test%B0,%1,%0);
  731.  
  732.   return AS2 (test%B1,%0,%1);
  733. }")
  734.  
  735. ;; move instructions.
  736. ;; There is one for each machine mode,
  737. ;; and each is preceded by a corresponding push-insn pattern
  738. ;; (since pushes are not general_operands on the 386).
  739.  
  740. (define_insn ""
  741.   [(set (match_operand:SI 0 "push_operand" "=<")
  742.     (match_operand:SI 1 "general_operand" "g"))]
  743.   "! TARGET_486"
  744.   "push%L0 %1")
  745.  
  746. ;; On a 486, it is faster to move MEM to a REG and then push, rather than
  747. ;; push MEM directly.
  748.  
  749. (define_insn ""
  750.   [(set (match_operand:SI 0 "push_operand" "=<")
  751.     (match_operand:SI 1 "general_operand" "ri"))]
  752.   "TARGET_486"
  753.   "push%L0 %1")
  754.  
  755. ;; General case of fullword move.
  756.  
  757. ;; If generating PIC code and operands[1] is a symbolic CONST, emit a
  758. ;; move to get the address of the symbolic object from the GOT.
  759.  
  760. (define_expand "movsi"
  761.   [(set (match_operand:SI 0 "general_operand" "")
  762.     (match_operand:SI 1 "general_operand" ""))]
  763.   ""
  764.   "
  765. {
  766.   extern int flag_pic;
  767.  
  768.   if (flag_pic && SYMBOLIC_CONST (operands[1]))
  769.     emit_pic_move (operands, SImode);
  770. }")
  771.  
  772. ;; On i486, incl reg is faster than movl $1,reg.
  773.  
  774. (define_insn ""
  775.   [(set (match_operand:SI 0 "general_operand" "=g,r")
  776.     (match_operand:SI 1 "general_operand" "ri,m"))]
  777.   ""
  778.   "*
  779. {
  780.   rtx link;
  781.   if (operands[1] == const0_rtx && REG_P (operands[0]))
  782.     return AS2 (xor%L0,%0,%0);
  783.  
  784.   if (operands[1] == const1_rtx
  785.       && (link = find_reg_note (insn, REG_WAS_0, 0))
  786.       /* Make sure the insn that stored the 0 is still present.  */
  787.       && ! INSN_DELETED_P (XEXP (link, 0))
  788.       && GET_CODE (XEXP (link, 0)) != NOTE
  789.       /* Make sure cross jumping didn't happen here.  */
  790.       && no_labels_between_p (XEXP (link, 0), insn)
  791.       /* Make sure the reg hasn't been clobbered.  */
  792.       && ! reg_set_between_p (operands[0], XEXP (link, 0), insn))
  793.     /* Fastest way to change a 0 to a 1.  */
  794.     return AS1 (inc%L0,%0);
  795.  
  796.   return AS2 (mov%L0,%1,%0);
  797. }")
  798.  
  799. (define_insn ""
  800.   [(set (match_operand:HI 0 "push_operand" "=<")
  801.     (match_operand:HI 1 "general_operand" "g"))]
  802.   ""
  803.   "push%W0 %1")
  804.  
  805. ;; On i486, an incl and movl are both faster than incw and movw.
  806.  
  807. (define_insn "movhi"
  808.   [(set (match_operand:HI 0 "general_operand" "=g,r")
  809.     (match_operand:HI 1 "general_operand" "ri,m"))]
  810.   ""
  811.   "*
  812. {
  813.   rtx link;
  814.   if (REG_P (operands[0]) && operands[1] == const0_rtx)
  815.     return AS2 (xor%L0,%k0,%k0);
  816.  
  817.   if (REG_P (operands[0]) && operands[1] == const1_rtx 
  818.       && (link = find_reg_note (insn, REG_WAS_0, 0))
  819.       /* Make sure the insn that stored the 0 is still present.  */
  820.       && ! INSN_DELETED_P (XEXP (link, 0))
  821.       && GET_CODE (XEXP (link, 0)) != NOTE
  822.       /* Make sure cross jumping didn't happen here.  */
  823.       && no_labels_between_p (XEXP (link, 0), insn)
  824.       /* Make sure the reg hasn't been clobbered.  */
  825.       && ! reg_set_between_p (operands[0], XEXP (link, 0), insn))
  826.     /* Fastest way to change a 0 to a 1.  */
  827.     return AS1 (inc%L0,%k0);
  828.  
  829.   if (REG_P (operands[0]))
  830.     {
  831.       if (REG_P (operands[1]))
  832.     return AS2 (mov%L0,%k1,%k0);
  833.       else if (CONSTANT_P (operands[1]))
  834.     return AS2 (mov%L0,%1,%k0);
  835.     }
  836.  
  837.   return AS2 (mov%W0,%1,%0);
  838. }")
  839.  
  840. (define_insn "movstricthi"
  841.   [(set (strict_low_part (match_operand:HI 0 "general_operand" "+g,r"))
  842.     (match_operand:HI 1 "general_operand" "ri,m"))]
  843.   ""
  844.   "*
  845. {
  846.   rtx link;
  847.   if (operands[1] == const0_rtx && REG_P (operands[0]))
  848.     return AS2 (xor%W0,%0,%0);
  849.  
  850.   if (operands[1] == const1_rtx
  851.       && (link = find_reg_note (insn, REG_WAS_0, 0))
  852.       /* Make sure the insn that stored the 0 is still present.  */
  853.       && ! INSN_DELETED_P (XEXP (link, 0))
  854.       && GET_CODE (XEXP (link, 0)) != NOTE
  855.       /* Make sure cross jumping didn't happen here.  */
  856.       && no_labels_between_p (XEXP (link, 0), insn)
  857.       /* Make sure the reg hasn't been clobbered.  */
  858.       && ! reg_set_between_p (operands[0], XEXP (link, 0), insn))
  859.     /* Fastest way to change a 0 to a 1.  */
  860.     return AS1 (inc%W0,%0);
  861.  
  862.   return AS2 (mov%W0,%1,%0);
  863. }")
  864.  
  865. ;; emit_push_insn when it calls move_by_pieces
  866. ;; requires an insn to "push a byte".
  867. ;; But actually we use pushw, which has the effect of rounding
  868. ;; the amount pushed up to a halfword.
  869. (define_insn ""
  870.   [(set (match_operand:QI 0 "push_operand" "=<")
  871.     (match_operand:QI 1 "general_operand" "q"))]
  872.   ""
  873.   "*
  874. {
  875.   operands[1] = gen_rtx (REG, HImode, REGNO (operands[1]));
  876.   return AS1 (push%W0,%1);
  877. }")
  878.  
  879. ;; On i486, incb reg is faster than movb $1,reg.
  880.  
  881. ;; ??? Do a recognizer for zero_extract that looks just like this, but reads
  882. ;; or writes %ah, %bh, %ch, %dh.
  883.  
  884. (define_insn "movqi"
  885.   [(set (match_operand:QI 0 "general_operand" "=q,*r,qm")
  886.     (match_operand:QI 1 "general_operand" "*g,q,qn"))]
  887.   ""
  888.   "*
  889. {
  890.   rtx link;
  891.   if (operands[1] == const0_rtx && REG_P (operands[0]))
  892.     return AS2 (xor%B0,%0,%0);
  893.  
  894.   if (operands[1] == const1_rtx
  895.       && (link = find_reg_note (insn, REG_WAS_0, 0))
  896.       /* Make sure the insn that stored the 0 is still present.  */
  897.       && ! INSN_DELETED_P (XEXP (link, 0))
  898.       && GET_CODE (XEXP (link, 0)) != NOTE
  899.       /* Make sure cross jumping didn't happen here.  */
  900.       && no_labels_between_p (XEXP (link, 0), insn)
  901.       /* Make sure the reg hasn't been clobbered.  */
  902.       && ! reg_set_between_p (operands[0], XEXP (link, 0), insn))
  903.     /* Fastest way to change a 0 to a 1.  */
  904.     return AS1 (inc%B0,%0);
  905.  
  906.   /* If mov%B0 isn't allowed for one of these regs, use mov%L0.  */
  907.   if (NON_QI_REG_P (operands[0]) || NON_QI_REG_P (operands[1]))
  908.     return (AS2 (mov%L0,%k1,%k0));
  909.  
  910.   return (AS2 (mov%B0,%1,%0));
  911. }")
  912.  
  913. ;; If it becomes necessary to support movstrictqi into %esi or %edi,
  914. ;; use the insn sequence:
  915. ;;
  916. ;;    shrdl $8,srcreg,dstreg
  917. ;;    rorl $24,dstreg
  918. ;;
  919. ;; If operands[1] is a constant, then an andl/orl sequence would be
  920. ;; faster.
  921.  
  922. (define_insn "movstrictqi"
  923.   [(set (strict_low_part (match_operand:QI 0 "general_operand" "+qm,q"))
  924.     (match_operand:QI 1 "general_operand" "*qn,m"))]
  925.   ""
  926.   "*
  927. {
  928.   rtx link;
  929.   if (operands[1] == const0_rtx && REG_P (operands[0]))
  930.     return AS2 (xor%B0,%0,%0);
  931.  
  932.   if (operands[1] == const1_rtx
  933.       && (link = find_reg_note (insn, REG_WAS_0, 0))
  934.       /* Make sure the insn that stored the 0 is still present.  */
  935.       && ! INSN_DELETED_P (XEXP (link, 0))
  936.       && GET_CODE (XEXP (link, 0)) != NOTE
  937.       /* Make sure cross jumping didn't happen here.  */
  938.       && no_labels_between_p (XEXP (link, 0), insn)
  939.       /* Make sure the reg hasn't been clobbered.  */
  940.       && ! reg_set_between_p (operands[0], XEXP (link, 0), insn))
  941.     /* Fastest way to change a 0 to a 1.  */
  942.     return AS1 (inc%B0,%0);
  943.  
  944.   /* If mov%B0 isn't allowed for one of these regs, use mov%L0.  */
  945.   if (NON_QI_REG_P (operands[0]) || NON_QI_REG_P (operands[1]))
  946.     {
  947.       abort ();
  948.       return (AS2 (mov%L0,%k1,%k0));
  949.     }
  950.  
  951.   return AS2 (mov%B0,%1,%0);
  952. }")
  953.  
  954. (define_insn ""
  955.   [(set (match_operand:SF 0 "push_operand" "=<,<")
  956.     (match_operand:SF 1 "general_operand" "gF,f"))]
  957.   ""
  958.   "*
  959. {
  960.   if (STACK_REG_P (operands[1]))
  961.     {
  962.       rtx xops[3];
  963.  
  964.       if (! STACK_TOP_P (operands[1]))
  965.         abort ();
  966.  
  967.       xops[0] = AT_SP (SFmode);
  968.       xops[1] = GEN_INT (4);
  969.       xops[2] = stack_pointer_rtx;
  970.  
  971.       output_asm_insn (AS2 (sub%L2,%1,%2), xops);
  972.  
  973.       if (find_regno_note (insn, REG_DEAD, FIRST_STACK_REG))
  974.         output_asm_insn (AS1 (fstp%S0,%0), xops);
  975.       else
  976.         output_asm_insn (AS1 (fst%S0,%0), xops);
  977.       RET;
  978.     }
  979.   return AS1 (push%L1,%1);
  980. }")
  981.  
  982. ;; Allow MEM-MEM moves before reload.  The reload class for such a
  983. ;; move will be ALL_REGS.  PREFERRED_RELOAD_CLASS will narrow this to
  984. ;; GENERAL_REGS.  For the purposes of regclass, prefer FLOAT_REGS.
  985.  
  986. (define_insn "movsf"
  987.   [(set (match_operand:SF 0 "general_operand" "=*rfm,*rf,f,!*rm")
  988.     (match_operand:SF 1 "general_operand" "*rf,*rfm,fG,fF"))]
  989.   ""
  990.   "*
  991. {
  992.   int stack_top_dies = find_regno_note (insn, REG_DEAD, FIRST_STACK_REG) != 0;
  993.  
  994.   /* First handle a `pop' insn or a `fld %st(0)' */
  995.  
  996.   if (STACK_TOP_P (operands[0]) && STACK_TOP_P (operands[1]))
  997.     {
  998.       if (stack_top_dies)
  999.     return AS1 (fstp,%y0);
  1000.       else
  1001.         return AS1 (fld,%y0);
  1002.     }
  1003.  
  1004.   /* Handle a transfer between the 387 and a 386 register */
  1005.  
  1006.   if (STACK_TOP_P (operands[0]) && NON_STACK_REG_P (operands[1]))
  1007.     {
  1008.       output_op_from_reg (operands[1], AS1 (fld%z0,%y1));
  1009.       RET;
  1010.     }
  1011.  
  1012.   if (STACK_TOP_P (operands[1]) && NON_STACK_REG_P (operands[0]))
  1013.     {
  1014.       output_to_reg (operands[0], stack_top_dies);
  1015.       RET;
  1016.     }
  1017.  
  1018.   /* Handle other kinds of writes from the 387 */
  1019.  
  1020.   if (STACK_TOP_P (operands[1]))
  1021.     {
  1022.       if (stack_top_dies)
  1023.     return AS1 (fstp%z0,%y0);
  1024.       else
  1025.         return AS1 (fst%z0,%y0);
  1026.     }
  1027.  
  1028.   /* Handle other kinds of reads to the 387 */
  1029.  
  1030.   if (STACK_TOP_P (operands[0]) && GET_CODE (operands[1]) == CONST_DOUBLE)
  1031.     return (char *) output_move_const_single (operands);
  1032.  
  1033.   if (STACK_TOP_P (operands[0]))
  1034.     return AS1 (fld%z1,%y1);
  1035.  
  1036.   /* Handle all SFmode moves not involving the 387 */
  1037.  
  1038.   return (char *) singlemove_string (operands);
  1039. }")
  1040.  
  1041. ;;should change to handle the memory operands[1] without doing df push..
  1042. (define_insn ""
  1043.   [(set (match_operand:DF 0 "push_operand" "=<,<")
  1044.     (match_operand:DF 1 "general_operand" "gF,f"))]
  1045.   ""
  1046.   "*
  1047. {
  1048.   if (STACK_REG_P (operands[1]))
  1049.     {
  1050.       rtx xops[3];
  1051.  
  1052.       xops[0] = AT_SP (SFmode);
  1053.       xops[1] = GEN_INT (8);
  1054.       xops[2] = stack_pointer_rtx;
  1055.  
  1056.       output_asm_insn (AS2 (sub%L2,%1,%2), xops);
  1057.  
  1058.       if (find_regno_note (insn, REG_DEAD, FIRST_STACK_REG))
  1059.         output_asm_insn (AS1 (fstp%Q0,%0), xops);
  1060.       else
  1061.         output_asm_insn (AS1 (fst%Q0,%0), xops);
  1062.  
  1063.       RET;
  1064.     }
  1065.   else
  1066.     return (char *) output_move_double (operands);
  1067. }")
  1068.  
  1069. (define_insn "swapdf"
  1070.   [(set (match_operand:DF 0 "register_operand" "f")
  1071.     (match_operand:DF 1 "register_operand" "f"))
  1072.    (set (match_dup 1)
  1073.     (match_dup 0))]
  1074.   ""
  1075.   "*
  1076. {
  1077.   if (STACK_TOP_P (operands[0]))
  1078.     return AS1 (fxch,%1);
  1079.   else
  1080.     return AS1 (fxch,%0);
  1081. }")
  1082.  
  1083. ;; Allow MEM-MEM moves before reload.  The reload class for such a
  1084. ;; move will be ALL_REGS.  PREFERRED_RELOAD_CLASS will narrow this to
  1085. ;; GENERAL_REGS.  For the purposes of regclass, prefer FLOAT_REGS.
  1086.  
  1087. (define_insn "movdf"
  1088.   [(set (match_operand:DF 0 "general_operand" "=*rfm,*rf,f,!*rm")
  1089.     (match_operand:DF 1 "general_operand" "*rf,*rfm,fG,fF"))]
  1090.   ""
  1091.   "*
  1092. {
  1093.   int stack_top_dies = find_regno_note (insn, REG_DEAD, FIRST_STACK_REG) != 0;
  1094.  
  1095.   /* First handle a `pop' insn or a `fld %st(0)' */
  1096.  
  1097.   if (STACK_TOP_P (operands[0]) && STACK_TOP_P (operands[1]))
  1098.     {
  1099.       if (stack_top_dies)
  1100.     return AS1 (fstp,%y0);
  1101.       else
  1102.         return AS1 (fld,%y0);
  1103.     }
  1104.  
  1105.   /* Handle a transfer between the 387 and a 386 register */
  1106.  
  1107.   if (STACK_TOP_P (operands[0]) && NON_STACK_REG_P (operands[1]))
  1108.     {
  1109.       output_op_from_reg (operands[1], AS1 (fld%z0,%y1));
  1110.       RET;
  1111.     }
  1112.  
  1113.   if (STACK_TOP_P (operands[1]) && NON_STACK_REG_P (operands[0]))
  1114.     {
  1115.       output_to_reg (operands[0], stack_top_dies);
  1116.       RET;
  1117.     }
  1118.  
  1119.   /* Handle other kinds of writes from the 387 */
  1120.  
  1121.   if (STACK_TOP_P (operands[1]))
  1122.     {
  1123.       if (stack_top_dies)
  1124.     return AS1 (fstp%z0,%y0);
  1125.       else
  1126.         return AS1 (fst%z0,%y0);
  1127.     }
  1128.  
  1129.   /* Handle other kinds of reads to the 387 */
  1130.  
  1131.   if (STACK_TOP_P (operands[0]) && GET_CODE (operands[1]) == CONST_DOUBLE)
  1132.     return (char *) output_move_const_single (operands);
  1133.  
  1134.   if (STACK_TOP_P (operands[0]))
  1135.     return AS1 (fld%z1,%y1);
  1136.  
  1137.   /* Handle all DFmode moves not involving the 387 */
  1138.  
  1139.   return (char *) output_move_double (operands);
  1140. }")
  1141.  
  1142. (define_insn ""
  1143.   [(set (match_operand:XF 0 "push_operand" "=<,<")
  1144.      (match_operand:XF 1 "general_operand" "gF,f"))]
  1145.   ""
  1146.   "*
  1147. {
  1148.   if (STACK_REG_P (operands[1]))
  1149.     {
  1150.       rtx xops[3];
  1151.  
  1152.       xops[0] = AT_SP (SFmode);
  1153.       xops[1] = GEN_INT (12);
  1154.       xops[2] = stack_pointer_rtx;
  1155.  
  1156.       output_asm_insn (AS2 (sub%L2,%1,%2), xops);
  1157.       output_asm_insn (AS1 (fstp%T0,%0), xops);
  1158.       if (! find_regno_note (insn, REG_DEAD, FIRST_STACK_REG))
  1159.     output_asm_insn (AS1 (fld%T0,%0), xops);
  1160.  
  1161.       RET;
  1162.     }
  1163.   else
  1164.     return (char *) output_move_double (operands);
  1165.  }")
  1166.  
  1167. (define_insn "swapxf"
  1168.   [(set (match_operand:XF 0 "register_operand" "f")
  1169.     (match_operand:XF 1 "register_operand" "f"))
  1170.    (set (match_dup 1)
  1171.     (match_dup 0))]
  1172.   ""
  1173.   "*
  1174. {
  1175.   if (STACK_TOP_P (operands[0]))
  1176.     return AS1 (fxch,%1);
  1177.   else
  1178.     return AS1 (fxch,%0);
  1179. }")
  1180.  
  1181. (define_insn "movxf"
  1182.   [(set (match_operand:XF 0 "general_operand" "=f,fm,!*rf,!*rm")
  1183.     (match_operand:XF 1 "general_operand" "fmG,f,*rfm,*rfF"))]
  1184. ;;  [(set (match_operand:XF 0 "general_operand" "=*rf,*rfm,f,!*rm")
  1185. ;;    (match_operand:XF 1 "general_operand" "*rfm,*rf,fG,fF"))]
  1186.   ""
  1187.   "*
  1188. {
  1189.   int stack_top_dies = find_regno_note (insn, REG_DEAD, FIRST_STACK_REG) != 0;
  1190.  
  1191.   /* First handle a `pop' insn or a `fld %st(0)' */
  1192.  
  1193.   if (STACK_TOP_P (operands[0]) && STACK_TOP_P (operands[1]))
  1194.     {
  1195.       if (stack_top_dies)
  1196.     return AS1 (fstp,%y0);
  1197.       else
  1198.         return AS1 (fld,%y0);
  1199.     }
  1200.  
  1201.   /* Handle a transfer between the 387 and a 386 register */
  1202.  
  1203.   if (STACK_TOP_P (operands[0]) && NON_STACK_REG_P (operands[1]))
  1204.     {
  1205.       output_op_from_reg (operands[1], AS1 (fld%z0,%y1));
  1206.       RET;
  1207.     }
  1208.  
  1209.   if (STACK_TOP_P (operands[1]) && NON_STACK_REG_P (operands[0]))
  1210.     {
  1211.       output_to_reg (operands[0], stack_top_dies);
  1212.       RET;
  1213.     }
  1214.  
  1215.   /* Handle other kinds of writes from the 387 */
  1216.  
  1217.   if (STACK_TOP_P (operands[1]))
  1218.     {
  1219.       output_asm_insn (AS1 (fstp%z0,%y0), operands);
  1220.       if (! stack_top_dies)
  1221.     return AS1 (fld%z0,%y0);
  1222.  
  1223.       RET;
  1224.     }
  1225.  
  1226.   /* Handle other kinds of reads to the 387 */
  1227.  
  1228.   if (STACK_TOP_P (operands[0]) && GET_CODE (operands[1]) == CONST_DOUBLE)
  1229.     return (char *) output_move_const_single (operands);
  1230.  
  1231.   if (STACK_TOP_P (operands[0]))
  1232.        return AS1 (fld%z1,%y1);
  1233.  
  1234.   /* Handle all XFmode moves not involving the 387 */
  1235.  
  1236.   return (char *) output_move_double (operands);
  1237. }")
  1238.  
  1239. (define_insn ""
  1240.   [(set (match_operand:DI 0 "push_operand" "=<")
  1241.     (match_operand:DI 1 "general_operand" "roiF"))]
  1242.   ""
  1243.   "*
  1244. {
  1245.   return (char *) output_move_double (operands);
  1246. }")
  1247.  
  1248. (define_insn "movdi"
  1249.   [(set (match_operand:DI 0 "general_operand" "=r,rm")
  1250.     (match_operand:DI 1 "general_operand" "m,riF"))]
  1251.   ""
  1252.   "*
  1253. {
  1254.   return (char *) output_move_double (operands);
  1255. }")
  1256.  
  1257. ;;- conversion instructions
  1258. ;;- NONE
  1259.  
  1260. ;;- zero extension instructions
  1261. ;; See comments by `andsi' for when andl is faster than movzx.
  1262.  
  1263. (define_insn "zero_extendhisi2"
  1264.   [(set (match_operand:SI 0 "general_operand" "=r")
  1265.     (zero_extend:SI
  1266.      (match_operand:HI 1 "nonimmediate_operand" "rm")))]
  1267.   ""
  1268.   "*
  1269. {
  1270.   if ((TARGET_486 || REGNO (operands[0]) == 0)
  1271.       && REG_P (operands[1]) && REGNO (operands[0]) == REGNO (operands[1]))
  1272.     {
  1273.       rtx xops[2];
  1274.       xops[0] = operands[0];
  1275.       xops[1] = GEN_INT (0xffff);
  1276.       output_asm_insn (AS2 (and%L0,%1,%k0), xops);
  1277.       RET;
  1278.     }
  1279.  
  1280. #ifdef INTEL_SYNTAX
  1281.   return AS2 (movzx,%1,%0);
  1282. #else
  1283.   return AS2 (movz%W0%L0,%1,%0);
  1284. #endif
  1285. }")
  1286.  
  1287. (define_insn "zero_extendqihi2"
  1288.   [(set (match_operand:HI 0 "general_operand" "=r")
  1289.     (zero_extend:HI
  1290.      (match_operand:QI 1 "nonimmediate_operand" "qm")))]
  1291.   ""
  1292.   "*
  1293. {
  1294.   if ((TARGET_486 || REGNO (operands[0]) == 0)
  1295.       && REG_P (operands[1]) && REGNO (operands[0]) == REGNO (operands[1]))
  1296.     {
  1297.       rtx xops[2];
  1298.       xops[0] = operands[0];
  1299.       xops[1] = GEN_INT (0xff);
  1300.       output_asm_insn (AS2 (and%L0,%1,%k0), xops);
  1301.       RET;
  1302.     }
  1303.  
  1304. #ifdef INTEL_SYNTAX
  1305.   return AS2 (movzx,%1,%0);
  1306. #else
  1307.   return AS2 (movz%B0%W0,%1,%0);
  1308. #endif
  1309. }")
  1310.  
  1311. (define_insn "zero_extendqisi2"
  1312.   [(set (match_operand:SI 0 "general_operand" "=r")
  1313.     (zero_extend:SI
  1314.      (match_operand:QI 1 "nonimmediate_operand" "qm")))]
  1315.   ""
  1316.   "*
  1317. {
  1318.   if ((TARGET_486 || REGNO (operands[0]) == 0)
  1319.       && REG_P (operands[1]) && REGNO (operands[0]) == REGNO (operands[1]))
  1320.     {
  1321.       rtx xops[2];
  1322.       xops[0] = operands[0];
  1323.       xops[1] = GEN_INT (0xff);
  1324.       output_asm_insn (AS2 (and%L0,%1,%k0), xops);
  1325.       RET;
  1326.     }
  1327.  
  1328. #ifdef INTEL_SYNTAX
  1329.   return AS2 (movzx,%1,%0);
  1330. #else
  1331.   return AS2 (movz%B0%L0,%1,%0);
  1332. #endif
  1333. }")
  1334.  
  1335. (define_insn "zero_extendsidi2"
  1336.   [(set (match_operand:DI 0 "register_operand" "=r")
  1337.     (zero_extend:DI
  1338.      (match_operand:SI 1 "register_operand" "0")))]
  1339.   ""
  1340.   "*
  1341. {
  1342.   operands[0] = gen_rtx (REG, SImode, REGNO (operands[0]) + 1);
  1343.   return AS2 (xor%L0,%0,%0);
  1344. }")
  1345.  
  1346. ;;- sign extension instructions
  1347.  
  1348. (define_insn "extendsidi2"
  1349.   [(set (match_operand:DI 0 "register_operand" "=r")
  1350.     (sign_extend:DI
  1351.      (match_operand:SI 1 "register_operand" "0")))]
  1352.   ""
  1353.   "*
  1354. {
  1355.   if (REGNO (operands[0]) == 0)
  1356.     {
  1357.       /* This used to be cwtl, but that extends HI to SI somehow.  */
  1358. #ifdef INTEL_SYNTAX
  1359.       return \"cdq\";
  1360. #else
  1361.       return \"cltd\";
  1362. #endif
  1363.     }
  1364.  
  1365.   operands[1] = gen_rtx (REG, SImode, REGNO (operands[0]) + 1);
  1366.   output_asm_insn (AS2 (mov%L0,%0,%1), operands);
  1367.  
  1368.   operands[0] = GEN_INT (31);
  1369.   return AS2 (sar%L1,%0,%1);
  1370. }")
  1371.  
  1372. ;; Note that the i386 programmers' manual says that the opcodes
  1373. ;; are named movsx..., but the assembler on Unix does not accept that.
  1374. ;; We use what the Unix assembler expects.
  1375.  
  1376. (define_insn "extendhisi2"
  1377.   [(set (match_operand:SI 0 "general_operand" "=r")
  1378.     (sign_extend:SI
  1379.      (match_operand:HI 1 "nonimmediate_operand" "rm")))]
  1380.   ""
  1381.   "*
  1382. {
  1383.   if (REGNO (operands[0]) == 0
  1384.       && REG_P (operands[1]) && REGNO (operands[1]) == 0)
  1385. #ifdef INTEL_SYNTAX
  1386.     return \"cwde\";
  1387. #else
  1388.     return \"cwtl\";
  1389. #endif
  1390.  
  1391. #ifdef INTEL_SYNTAX
  1392.   return AS2 (movsx,%1,%0);
  1393. #else
  1394.   return AS2 (movs%W0%L0,%1,%0);
  1395. #endif
  1396. }")
  1397.  
  1398. (define_insn "extendqihi2"
  1399.   [(set (match_operand:HI 0 "general_operand" "=r")
  1400.     (sign_extend:HI
  1401.      (match_operand:QI 1 "nonimmediate_operand" "qm")))]
  1402.   ""
  1403.   "*
  1404. {
  1405.   if (REGNO (operands[0]) == 0
  1406.       && REG_P (operands[1]) && REGNO (operands[1]) == 0)
  1407.     return \"cbtw\";
  1408.  
  1409. #ifdef INTEL_SYNTAX
  1410.   return AS2 (movsx,%1,%0);
  1411. #else
  1412.   return AS2 (movs%B0%W0,%1,%0);
  1413. #endif
  1414. }")
  1415.  
  1416. (define_insn "extendqisi2"
  1417.   [(set (match_operand:SI 0 "general_operand" "=r")
  1418.     (sign_extend:SI
  1419.      (match_operand:QI 1 "nonimmediate_operand" "qm")))]
  1420.   ""
  1421.   "*
  1422. {
  1423. #ifdef INTEL_SYNTAX
  1424.   return AS2 (movsx,%1,%0);
  1425. #else
  1426.   return AS2 (movs%B0%L0,%1,%0);
  1427. #endif
  1428. }")
  1429.  
  1430. ;; Conversions between float and double.
  1431.  
  1432. (define_insn "extendsfdf2"
  1433.   [(set (match_operand:DF 0 "general_operand" "=fm,f")
  1434.     (float_extend:DF
  1435.      (match_operand:SF 1 "general_operand" "f,fm")))]
  1436.   "TARGET_80387"
  1437.   "*
  1438. {
  1439.   int stack_top_dies = find_regno_note (insn, REG_DEAD, FIRST_STACK_REG) != 0;
  1440.  
  1441.   if (NON_STACK_REG_P (operands[1]))
  1442.     {
  1443.       output_op_from_reg (operands[1], AS1 (fld%z0,%y1));
  1444.       RET;
  1445.     }
  1446.  
  1447.   if (NON_STACK_REG_P (operands[0]))
  1448.     {
  1449.       output_to_reg (operands[0], stack_top_dies);
  1450.       RET;
  1451.     }
  1452.  
  1453.   if (STACK_TOP_P (operands[0]))
  1454.     return AS1 (fld%z1,%y1);
  1455.  
  1456.   if (GET_CODE (operands[0]) == MEM)
  1457.     {
  1458.       if (stack_top_dies)
  1459.     return AS1 (fstp%z0,%y0);
  1460.       else
  1461.         return AS1 (fst%z0,%y0);
  1462.     }
  1463.  
  1464.   abort ();
  1465. }")
  1466.  
  1467. (define_insn "extenddfxf2"
  1468.   [(set (match_operand:XF 0 "general_operand" "=fm,f,f,!*r")
  1469.     (float_extend:XF
  1470.      (match_operand:DF 1 "general_operand" "f,fm,!*r,f")))]
  1471.   "TARGET_80387"
  1472.   "*
  1473. {
  1474.   int stack_top_dies = find_regno_note (insn, REG_DEAD, FIRST_STACK_REG) != 0;
  1475.  
  1476.   if (NON_STACK_REG_P (operands[1]))
  1477.     {
  1478.       output_op_from_reg (operands[1], AS1 (fld%z0,%y1));
  1479.       RET;
  1480.     }
  1481.  
  1482.   if (NON_STACK_REG_P (operands[0]))
  1483.     {
  1484.       output_to_reg (operands[0], stack_top_dies);
  1485.       RET;
  1486.     }
  1487.  
  1488.   if (STACK_TOP_P (operands[0]))
  1489.     return AS1 (fld%z1,%y1);
  1490.  
  1491.   if (GET_CODE (operands[0]) == MEM)
  1492.     {
  1493.       output_asm_insn (AS1 (fstp%z0,%y0), operands);
  1494.       if (! stack_top_dies)
  1495.     return AS1 (fld%z0,%y0);
  1496.       RET;
  1497.     }
  1498.  
  1499.   abort ();
  1500. }")
  1501.  
  1502. (define_insn "extendsfxf2"
  1503.   [(set (match_operand:XF 0 "general_operand" "=fm,f,f,!*r")
  1504.     (float_extend:XF
  1505.      (match_operand:SF 1 "general_operand" "f,fm,!*r,f")))]
  1506.   "TARGET_80387"
  1507.   "*
  1508. {
  1509.   int stack_top_dies = find_regno_note (insn, REG_DEAD, FIRST_STACK_REG) != 0;
  1510.  
  1511.   if (NON_STACK_REG_P (operands[1]))
  1512.     {
  1513.       output_op_from_reg (operands[1], AS1 (fld%z0,%y1));
  1514.       RET;
  1515.     }
  1516.  
  1517.   if (NON_STACK_REG_P (operands[0]))
  1518.     {
  1519.       output_to_reg (operands[0], stack_top_dies);
  1520.       RET;
  1521.     }
  1522.  
  1523.   if (STACK_TOP_P (operands[0]))
  1524.     return AS1 (fld%z1,%y1);
  1525.  
  1526.   if (GET_CODE (operands[0]) == MEM)
  1527.     {
  1528.       output_asm_insn (AS1 (fstp%z0,%y0), operands);
  1529.       if (! stack_top_dies)
  1530.     return AS1 (fld%z0,%y0);
  1531.       RET;
  1532.     }
  1533.  
  1534.   abort ();
  1535. }")
  1536.  
  1537. (define_expand "truncdfsf2"
  1538.   [(parallel [(set (match_operand:SF 0 "nonimmediate_operand" "")
  1539.            (float_truncate:SF
  1540.             (match_operand:DF 1 "register_operand" "")))
  1541.           (clobber (match_dup 2))])]
  1542.   "TARGET_80387"
  1543.   "
  1544. {
  1545.   operands[2] = (rtx) assign_386_stack_local (SFmode, 0);
  1546. }")
  1547.  
  1548. ;; This cannot output into an f-reg because there is no way to be sure
  1549. ;; of truncating in that case.  Otherwise this is just like a simple move
  1550. ;; insn.  So we pretend we can output to a reg in order to get better
  1551. ;; register preferencing, but we really use a stack slot.
  1552.  
  1553. (define_insn ""
  1554.   [(set (match_operand:SF 0 "nonimmediate_operand" "=f,m")
  1555.     (float_truncate:SF
  1556.      (match_operand:DF 1 "register_operand" "0,f")))
  1557.    (clobber (match_operand:SF 2 "memory_operand" "m,m"))]
  1558.   "TARGET_80387"
  1559.   "*
  1560. {
  1561.   int stack_top_dies = find_regno_note (insn, REG_DEAD, FIRST_STACK_REG) != 0;
  1562.  
  1563.   if (GET_CODE (operands[0]) == MEM)
  1564.     {
  1565.       if (stack_top_dies)
  1566.     return AS1 (fstp%z0,%0);
  1567.       else
  1568.         return AS1 (fst%z0,%0);
  1569.     }
  1570.   else if (STACK_TOP_P (operands[0]))
  1571.     {
  1572.       output_asm_insn (AS1 (fstp%z2,%y2), operands);
  1573.       return AS1 (fld%z2,%y2);
  1574.     }
  1575.   else
  1576.     abort ();
  1577. }")
  1578.  
  1579. (define_insn "truncxfsf2"
  1580.   [(set (match_operand:SF 0 "general_operand" "=m,!*r")
  1581.     (float_truncate:SF
  1582.      (match_operand:XF 1 "register_operand" "f,f")))]
  1583.   "TARGET_80387"
  1584.   "*
  1585. {
  1586.   int stack_top_dies = find_regno_note (insn, REG_DEAD, FIRST_STACK_REG) != 0;
  1587.  
  1588.   if (NON_STACK_REG_P (operands[0]))
  1589.     {
  1590.       if (stack_top_dies == 0)
  1591.     {
  1592.       output_asm_insn (AS1 (fld,%y1), operands);
  1593.       stack_top_dies = 1;
  1594.     }
  1595.       output_to_reg (operands[0], stack_top_dies);
  1596.       RET;
  1597.     }
  1598.   else if (GET_CODE (operands[0]) == MEM)
  1599.     {
  1600.       if (stack_top_dies)
  1601.     return AS1 (fstp%z0,%0);
  1602.       else
  1603.     {
  1604.       output_asm_insn (AS1 (fld,%y1), operands);
  1605.       return AS1 (fstp%z0,%0);
  1606.     }
  1607.     }
  1608.   else
  1609.     abort ();
  1610. }")
  1611.  
  1612. (define_insn "truncxfdf2"
  1613.   [(set (match_operand:DF 0 "general_operand" "=m,!*r")
  1614.     (float_truncate:DF
  1615.      (match_operand:XF 1 "register_operand" "f,f")))]
  1616.   "TARGET_80387"
  1617.   "*
  1618. {
  1619.   int stack_top_dies = find_regno_note (insn, REG_DEAD, FIRST_STACK_REG) != 0;
  1620.  
  1621.   if (NON_STACK_REG_P (operands[0]))
  1622.     {
  1623.       if (stack_top_dies == 0)
  1624.     {
  1625.       output_asm_insn (AS1 (fld,%y1), operands);
  1626.       stack_top_dies = 1;
  1627.     }
  1628.       output_to_reg (operands[0], stack_top_dies);
  1629.       RET;
  1630.     }
  1631.   else if (GET_CODE (operands[0]) == MEM)
  1632.     {
  1633.       if (stack_top_dies)
  1634.     return AS1 (fstp%z0,%0);
  1635.       else
  1636.     {
  1637.       output_asm_insn (AS1 (fld,%y1), operands);
  1638.       return AS1 (fstp%z0,%0);
  1639.     }
  1640.     }
  1641.   else
  1642.     abort ();
  1643. }")
  1644.  
  1645.  
  1646. ;; The 387 requires that the stack top dies after converting to DImode.
  1647.  
  1648. ;; Represent an unsigned conversion from SImode to MODE_FLOAT by first
  1649. ;; doing a signed conversion to DImode, and then taking just the low
  1650. ;; part.
  1651.  
  1652. (define_expand "fixuns_truncxfsi2"
  1653.   [(set (match_dup 4)
  1654.     (match_operand:XF 1 "register_operand" ""))
  1655.    (parallel [(set (match_dup 2)
  1656.            (fix:DI (fix:XF (match_dup 4))))
  1657.           (clobber (match_dup 4))
  1658.           (clobber (match_dup 5))
  1659.           (clobber (match_dup 6))
  1660.           (clobber (match_scratch:SI 7 ""))])
  1661.    (set (match_operand:SI 0 "general_operand" "")
  1662.     (match_dup 3))]
  1663.   "TARGET_80387"
  1664.   "
  1665. {
  1666.   operands[2] = gen_reg_rtx (DImode);
  1667.   operands[3] = gen_lowpart (SImode, operands[2]);
  1668.   operands[4] = gen_reg_rtx (XFmode);
  1669.   operands[5] = (rtx) assign_386_stack_local (SImode, 0);
  1670.   operands[6] = (rtx) assign_386_stack_local (SImode, 1);
  1671. }")
  1672.  
  1673. (define_expand "fixuns_truncdfsi2"
  1674.   [(set (match_dup 4)
  1675.     (match_operand:DF 1 "register_operand" ""))
  1676.    (parallel [(set (match_dup 2)
  1677.            (fix:DI (fix:DF (match_dup 4))))
  1678.           (clobber (match_dup 4))
  1679.           (clobber (match_dup 5))
  1680.           (clobber (match_dup 6))
  1681.           (clobber (match_scratch:SI 7 ""))])
  1682.    (set (match_operand:SI 0 "general_operand" "")
  1683.     (match_dup 3))]
  1684.   "TARGET_80387"
  1685.   "
  1686. {
  1687.   operands[2] = gen_reg_rtx (DImode);
  1688.   operands[3] = gen_lowpart (SImode, operands[2]);
  1689.   operands[4] = gen_reg_rtx (DFmode);
  1690.   operands[5] = (rtx) assign_386_stack_local (SImode, 0);
  1691.   operands[6] = (rtx) assign_386_stack_local (SImode, 1);
  1692. }")
  1693.  
  1694. (define_expand "fixuns_truncsfsi2"
  1695.   [(set (match_dup 4)
  1696.     (match_operand:SF 1 "register_operand" ""))
  1697.    (parallel [(set (match_dup 2)
  1698.            (fix:DI (fix:SF (match_dup 4))))
  1699.           (clobber (match_dup 4))
  1700.           (clobber (match_dup 5))
  1701.           (clobber (match_dup 6))
  1702.           (clobber (match_scratch:SI 7 ""))])
  1703.    (set (match_operand:SI 0 "general_operand" "")
  1704.     (match_dup 3))]
  1705.   "TARGET_80387"
  1706.   "
  1707. {
  1708.   operands[2] = gen_reg_rtx (DImode);
  1709.   operands[3] = gen_lowpart (SImode, operands[2]);
  1710.   operands[4] = gen_reg_rtx (SFmode);
  1711.   operands[5] = (rtx) assign_386_stack_local (SImode, 0);
  1712.   operands[6] = (rtx) assign_386_stack_local (SImode, 1);
  1713. }")
  1714.  
  1715. ;; Signed conversion to DImode.
  1716.  
  1717. (define_expand "fix_truncxfdi2"
  1718.   [(set (match_dup 2)
  1719.     (match_operand:XF 1 "register_operand" ""))
  1720.    (parallel [(set (match_operand:DI 0 "general_operand" "")
  1721.            (fix:DI (fix:XF (match_dup 2))))
  1722.           (clobber (match_dup 2))
  1723.           (clobber (match_dup 3))
  1724.           (clobber (match_dup 4))
  1725.           (clobber (match_scratch:SI 5 ""))])]
  1726.   "TARGET_80387"
  1727.   "
  1728. {
  1729.   operands[1] = copy_to_mode_reg (XFmode, operands[1]);
  1730.   operands[2] = gen_reg_rtx (XFmode);
  1731.   operands[3] = (rtx) assign_386_stack_local (SImode, 0);
  1732.   operands[4] = (rtx) assign_386_stack_local (SImode, 1);
  1733. }")
  1734.  
  1735. (define_expand "fix_truncdfdi2"
  1736.   [(set (match_dup 2)
  1737.     (match_operand:DF 1 "register_operand" ""))
  1738.    (parallel [(set (match_operand:DI 0 "general_operand" "")
  1739.            (fix:DI (fix:DF (match_dup 2))))
  1740.           (clobber (match_dup 2))
  1741.           (clobber (match_dup 3))
  1742.           (clobber (match_dup 4))
  1743.           (clobber (match_scratch:SI 5 ""))])]
  1744.   "TARGET_80387"
  1745.   "
  1746. {
  1747.   operands[1] = copy_to_mode_reg (DFmode, operands[1]);
  1748.   operands[2] = gen_reg_rtx (DFmode);
  1749.   operands[3] = (rtx) assign_386_stack_local (SImode, 0);
  1750.   operands[4] = (rtx) assign_386_stack_local (SImode, 1);
  1751. }")
  1752.  
  1753. (define_expand "fix_truncsfdi2"
  1754.   [(set (match_dup 2)
  1755.     (match_operand:SF 1 "register_operand" ""))
  1756.    (parallel [(set (match_operand:DI 0 "general_operand" "")
  1757.            (fix:DI (fix:SF (match_dup 2))))
  1758.           (clobber (match_dup 2))
  1759.           (clobber (match_dup 3))
  1760.           (clobber (match_dup 4))
  1761.           (clobber (match_scratch:SI 5 ""))])]
  1762.   "TARGET_80387"
  1763.   "
  1764. {
  1765.   operands[1] = copy_to_mode_reg (SFmode, operands[1]);
  1766.   operands[2] = gen_reg_rtx (SFmode);
  1767.   operands[3] = (rtx) assign_386_stack_local (SImode, 0);
  1768.   operands[4] = (rtx) assign_386_stack_local (SImode, 1);
  1769. }")
  1770.  
  1771. ;; These match a signed conversion of either DFmode or SFmode to DImode.
  1772.  
  1773. (define_insn ""
  1774.   [(set (match_operand:DI 0 "general_operand" "=rm")
  1775.     (fix:DI (fix:XF (match_operand:XF 1 "register_operand" "f"))))
  1776.    (clobber (match_dup 1))
  1777.    (clobber (match_operand:SI 2 "memory_operand" "m"))
  1778.    (clobber (match_operand:SI 3 "memory_operand" "m"))
  1779.    (clobber (match_scratch:SI 4 "=&q"))]
  1780.   "TARGET_80387"
  1781.   "* return (char *) output_fix_trunc (insn, operands);")
  1782.  
  1783. (define_insn ""
  1784.   [(set (match_operand:DI 0 "general_operand" "=rm")
  1785.     (fix:DI (fix:DF (match_operand:DF 1 "register_operand" "f"))))
  1786.    (clobber (match_dup 1))
  1787.    (clobber (match_operand:SI 2 "memory_operand" "m"))
  1788.    (clobber (match_operand:SI 3 "memory_operand" "m"))
  1789.    (clobber (match_scratch:SI 4 "=&q"))]
  1790.   "TARGET_80387"
  1791.   "* return (char *) output_fix_trunc (insn, operands);")
  1792.  
  1793. (define_insn ""
  1794.   [(set (match_operand:DI 0 "general_operand" "=rm")
  1795.     (fix:DI (fix:SF (match_operand:SF 1 "register_operand" "f"))))
  1796.    (clobber (match_dup 1))
  1797.    (clobber (match_operand:SI 2 "memory_operand" "m"))
  1798.    (clobber (match_operand:SI 3 "memory_operand" "m"))
  1799.    (clobber (match_scratch:SI 4 "=&q"))]
  1800.   "TARGET_80387"
  1801.   "* return (char *) output_fix_trunc (insn, operands);")
  1802.  
  1803. ;; Signed MODE_FLOAT conversion to SImode.
  1804.  
  1805. (define_expand "fix_truncxfsi2"
  1806.   [(parallel [(set (match_operand:SI 0 "general_operand" "")
  1807.            (fix:SI
  1808.             (fix:XF (match_operand:XF 1 "register_operand" ""))))
  1809.           (clobber (match_dup 2))
  1810.           (clobber (match_dup 3))
  1811.           (clobber (match_scratch:SI 4 ""))])]
  1812.   "TARGET_80387"
  1813.   "
  1814. {
  1815.   operands[2] = (rtx) assign_386_stack_local (SImode, 0);
  1816.   operands[3] = (rtx) assign_386_stack_local (SImode, 1);
  1817. }")
  1818.  
  1819. (define_expand "fix_truncdfsi2"
  1820.   [(parallel [(set (match_operand:SI 0 "general_operand" "")
  1821.            (fix:SI
  1822.             (fix:DF (match_operand:DF 1 "register_operand" ""))))
  1823.           (clobber (match_dup 2))
  1824.           (clobber (match_dup 3))
  1825.           (clobber (match_scratch:SI 4 ""))])]
  1826.   "TARGET_80387"
  1827.   "
  1828. {
  1829.   operands[2] = (rtx) assign_386_stack_local (SImode, 0);
  1830.   operands[3] = (rtx) assign_386_stack_local (SImode, 1);
  1831. }")
  1832.  
  1833. (define_expand "fix_truncsfsi2"
  1834.   [(parallel [(set (match_operand:SI 0 "general_operand" "")
  1835.            (fix:SI
  1836.             (fix:SF (match_operand:SF 1 "register_operand" ""))))
  1837.           (clobber (match_dup 2))
  1838.           (clobber (match_dup 3))
  1839.           (clobber (match_scratch:SI 4 ""))])]
  1840.   "TARGET_80387"
  1841.   "
  1842. {
  1843.   operands[2] = (rtx) assign_386_stack_local (SImode, 0);
  1844.   operands[3] = (rtx) assign_386_stack_local (SImode, 1);
  1845. }")
  1846.  
  1847. (define_insn ""
  1848.   [(set (match_operand:SI 0 "general_operand" "=rm")
  1849.     (fix:SI (fix:XF (match_operand:XF 1 "register_operand" "f"))))
  1850.    (clobber (match_operand:SI 2 "memory_operand" "m"))
  1851.    (clobber (match_operand:SI 3 "memory_operand" "m"))
  1852.    (clobber (match_scratch:SI 4 "=&q"))]
  1853.   "TARGET_80387"
  1854.   "* return (char *) output_fix_trunc (insn, operands);")
  1855.  
  1856. (define_insn ""
  1857.   [(set (match_operand:SI 0 "general_operand" "=rm")
  1858.     (fix:SI (fix:DF (match_operand:DF 1 "register_operand" "f"))))
  1859.    (clobber (match_operand:SI 2 "memory_operand" "m"))
  1860.    (clobber (match_operand:SI 3 "memory_operand" "m"))
  1861.    (clobber (match_scratch:SI 4 "=&q"))]
  1862.   "TARGET_80387"
  1863.   "* return (char *) output_fix_trunc (insn, operands);")
  1864.  
  1865. (define_insn ""
  1866.   [(set (match_operand:SI 0 "general_operand" "=rm")
  1867.     (fix:SI (fix:SF (match_operand:SF 1 "register_operand" "f"))))
  1868.    (clobber (match_operand:SI 2 "memory_operand" "m"))
  1869.    (clobber (match_operand:SI 3 "memory_operand" "m"))
  1870.    (clobber (match_scratch:SI 4 "=&q"))]
  1871.   "TARGET_80387"
  1872.   "* return (char *) output_fix_trunc (insn, operands);")
  1873.  
  1874. ;; Conversion between fixed point and floating point.
  1875. ;; The actual pattern that matches these is at the end of this file.
  1876.  
  1877. ;; ??? Possibly represent floatunssidf2 here in gcc2.
  1878.  
  1879. (define_expand "floatsisf2"
  1880.   [(set (match_operand:SF 0 "register_operand" "")
  1881.     (float:SF (match_operand:SI 1 "nonimmediate_operand" "")))]
  1882.   "TARGET_80387"
  1883.   "")
  1884.  
  1885. (define_expand "floatdisf2"
  1886.   [(set (match_operand:SF 0 "register_operand" "")
  1887.     (float:SF (match_operand:DI 1 "nonimmediate_operand" "")))]
  1888.   "TARGET_80387"
  1889.   "")
  1890.  
  1891. (define_expand "floatsidf2"
  1892.   [(set (match_operand:DF 0 "register_operand" "")
  1893.     (float:DF (match_operand:SI 1 "nonimmediate_operand" "")))]
  1894.   "TARGET_80387"
  1895.   "")
  1896.  
  1897. (define_expand "floatdidf2"
  1898.   [(set (match_operand:DF 0 "register_operand" "")
  1899.     (float:DF (match_operand:DI 1 "nonimmediate_operand" "")))]
  1900.   "TARGET_80387"
  1901.   "")
  1902.  
  1903. (define_expand "floatsixf2"
  1904.   [(set (match_operand:XF 0 "register_operand" "")
  1905.     (float:XF (match_operand:SI 1 "nonimmediate_operand" "")))]
  1906.   "TARGET_80387"
  1907.   "")
  1908.  
  1909. (define_expand "floatdixf2"
  1910.   [(set (match_operand:XF 0 "register_operand" "")
  1911.     (float:XF (match_operand:DI 1 "nonimmediate_operand" "")))]
  1912.   "TARGET_80387"
  1913.   "")
  1914.  
  1915. ;; This will convert from SImode or DImode to MODE_FLOAT.
  1916.  
  1917. (define_insn ""
  1918.   [(set (match_operand:XF 0 "register_operand" "=f")
  1919.     (float:XF (match_operand:DI 1 "general_operand" "rm")))]
  1920.   "TARGET_80387"
  1921.   "*
  1922. {
  1923.   if (NON_STACK_REG_P (operands[1]))
  1924.     {
  1925.       output_op_from_reg (operands[1], AS1 (fild%z0,%1));
  1926.       RET;
  1927.     }
  1928.   else if (GET_CODE (operands[1]) == MEM)
  1929.     return AS1 (fild%z1,%1);
  1930.   else
  1931.     abort ();
  1932. }")
  1933.  
  1934. (define_insn ""
  1935.   [(set (match_operand:DF 0 "register_operand" "=f")
  1936.     (float:DF (match_operand:DI 1 "nonimmediate_operand" "rm")))]
  1937.   "TARGET_80387"
  1938.   "*
  1939. {
  1940.   if (NON_STACK_REG_P (operands[1]))
  1941.     {
  1942.       output_op_from_reg (operands[1], AS1 (fild%z0,%1));
  1943.       RET;
  1944.     }
  1945.   else if (GET_CODE (operands[1]) == MEM)
  1946.     return AS1 (fild%z1,%1);
  1947.   else
  1948.     abort ();
  1949. }")
  1950.  
  1951. (define_insn ""
  1952.   [(set (match_operand:SF 0 "register_operand" "=f")
  1953.     (float:SF (match_operand:DI 1 "nonimmediate_operand" "rm")))]
  1954.   "TARGET_80387"
  1955.   "*
  1956. {
  1957.   if (NON_STACK_REG_P (operands[1]))
  1958.     {
  1959.       output_op_from_reg (operands[1], AS1 (fild%z0,%1));
  1960.       RET;
  1961.     }
  1962.   else if (GET_CODE (operands[1]) == MEM)
  1963.     return AS1 (fild%z1,%1);
  1964.   else
  1965.     abort ();
  1966. }")
  1967.  
  1968. (define_insn ""
  1969.   [(set (match_operand:DF 0 "register_operand" "=f")
  1970.     (float:DF (match_operand:SI 1 "nonimmediate_operand" "rm")))]
  1971.   "TARGET_80387"
  1972.   "*
  1973. {
  1974.   if (NON_STACK_REG_P (operands[1]))
  1975.     {
  1976.       output_op_from_reg (operands[1], AS1 (fild%z0,%1));
  1977.       RET;
  1978.     }
  1979.   else if (GET_CODE (operands[1]) == MEM)
  1980.     return AS1 (fild%z1,%1);
  1981.   else
  1982.     abort ();
  1983. }")
  1984.  
  1985. (define_insn ""
  1986.   [(set (match_operand:XF 0 "register_operand" "=f,f")
  1987.     (float:XF (match_operand:SI 1 "general_operand" "m,!*r")))]
  1988.   "TARGET_80387"
  1989.   "*
  1990. {
  1991.   if (NON_STACK_REG_P (operands[1]))
  1992.     {
  1993.       output_op_from_reg (operands[1], AS1 (fild%z0,%1));
  1994.       RET;
  1995.     }
  1996.   else if (GET_CODE (operands[1]) == MEM)
  1997.     return AS1 (fild%z1,%1);
  1998.   else
  1999.     abort ();
  2000. }")
  2001.  
  2002. (define_insn ""
  2003.   [(set (match_operand:SF 0 "register_operand" "=f")
  2004.     (float:SF (match_operand:SI 1 "nonimmediate_operand" "rm")))]
  2005.   "TARGET_80387"
  2006.   "*
  2007. {
  2008.   if (NON_STACK_REG_P (operands[1]))
  2009.     {
  2010.       output_op_from_reg (operands[1], AS1 (fild%z0,%1));
  2011.       RET;
  2012.     }
  2013.   else if (GET_CODE (operands[1]) == MEM)
  2014.     return AS1 (fild%z1,%1);
  2015.   else
  2016.     abort ();
  2017. }")
  2018.  
  2019. ;;- add instructions
  2020.  
  2021. (define_insn "adddi3"
  2022.   [(set (match_operand:DI 0 "general_operand" "=&r,ro")
  2023.     (plus:DI (match_operand:DI 1 "general_operand" "%0,0")
  2024.          (match_operand:DI 2 "general_operand" "o,riF")))]
  2025.   ""
  2026.   "*
  2027. {
  2028.   rtx low[3], high[3];
  2029.  
  2030.   CC_STATUS_INIT;
  2031.  
  2032.   split_di (operands, 3, low, high);
  2033.  
  2034.   if (GET_CODE (low[2]) != CONST_INT || INTVAL (low[2]) != 0)
  2035.     {
  2036.       output_asm_insn (AS2 (add%L0,%2,%0), low);
  2037.       output_asm_insn (AS2 (adc%L0,%2,%0), high);
  2038.     }
  2039.   else
  2040.     output_asm_insn (AS2 (add%L0,%2,%0), high);
  2041.   RET;
  2042. }")
  2043.  
  2044. ;; On a 486, it is faster to do movl/addl than to do a single leal if
  2045. ;; operands[1] and operands[2] are both registers.
  2046.  
  2047. (define_insn "addsi3"
  2048.   [(set (match_operand:SI 0 "general_operand" "=?r,rm,r")
  2049.     (plus:SI (match_operand:SI 1 "general_operand" "%r,0,0")
  2050.          (match_operand:SI 2 "general_operand" "ri,ri,rm")))]
  2051.   ""
  2052.   "*
  2053. {
  2054.   if (REG_P (operands[0]) && REGNO (operands[0]) != REGNO (operands[1]))
  2055.     {
  2056.       if (REG_P (operands[2]) && REGNO (operands[0]) == REGNO (operands[2]))
  2057.     return AS2 (add%L0,%1,%0);
  2058.  
  2059.       if (! TARGET_486 || ! REG_P (operands[2]))
  2060.         {
  2061.       CC_STATUS_INIT;
  2062.  
  2063.       if (operands[2] == stack_pointer_rtx)
  2064.         {
  2065.           rtx temp;
  2066.  
  2067.           temp = operands[1];
  2068.           operands[1] = operands[2];
  2069.           operands[2] = temp;
  2070.         }
  2071.       if (operands[2] != stack_pointer_rtx)
  2072.         {
  2073.           operands[1] = SET_SRC (PATTERN (insn));
  2074.           return AS2 (lea%L0,%a1,%0);
  2075.         }
  2076.     }
  2077.  
  2078.       output_asm_insn (AS2 (mov%L0,%1,%0), operands);
  2079.     }
  2080.  
  2081.   if (operands[2] == const1_rtx)
  2082.     return AS1 (inc%L0,%0);
  2083.  
  2084.   if (operands[2] == constm1_rtx)
  2085.     return AS1 (dec%L0,%0);
  2086.  
  2087.   return AS2 (add%L0,%2,%0);
  2088. }")
  2089.  
  2090. ;; ??? `lea' here, for three operand add?  If leaw is used, only %bx,
  2091. ;; %si and %di can appear in SET_SRC, and output_asm_insn might not be
  2092. ;; able to handle the operand.  But leal always works?
  2093.  
  2094. (define_insn "addhi3"
  2095.   [(set (match_operand:HI 0 "general_operand" "=rm,r")
  2096.     (plus:HI (match_operand:HI 1 "general_operand" "%0,0")
  2097.          (match_operand:HI 2 "general_operand" "ri,rm")))]
  2098.   ""
  2099.   "*
  2100. {
  2101.   /* ??? what about offsettable memory references? */
  2102.   if (QI_REG_P (operands[0])
  2103.       && GET_CODE (operands[2]) == CONST_INT
  2104.       && (INTVAL (operands[2]) & 0xff) == 0)
  2105.     {
  2106.       CC_STATUS_INIT;
  2107.  
  2108.       operands[2] = GEN_INT ((INTVAL (operands[2]) >> 8) & 0xff);
  2109.  
  2110.       if (operands[2] == const1_rtx)
  2111.     return AS1 (inc%B0,%h0);
  2112.  
  2113.       if (operands[2] == constm1_rtx)
  2114.     return AS1 (dec%B0,%h0);
  2115.  
  2116.       return AS2 (add%B0,%2,%h0);
  2117.     }
  2118.  
  2119.   if (operands[2] == const1_rtx)
  2120.     return AS1 (inc%W0,%0);
  2121.  
  2122.   if (operands[2] == constm1_rtx)
  2123.     return AS1 (dec%W0,%0);
  2124.  
  2125.   return AS2 (add%W0,%2,%0);
  2126. }")
  2127.  
  2128. (define_insn "addqi3"
  2129.   [(set (match_operand:QI 0 "general_operand" "=qm,q")
  2130.     (plus:QI (match_operand:QI 1 "general_operand" "%0,0")
  2131.          (match_operand:QI 2 "general_operand" "qn,qmn")))]
  2132.   ""
  2133.   "*
  2134. {
  2135.   if (operands[2] == const1_rtx)
  2136.     return AS1 (inc%B0,%0);
  2137.  
  2138.   if (operands[2] == constm1_rtx)
  2139.     return AS1 (dec%B0,%0);
  2140.  
  2141.   return AS2 (add%B0,%2,%0);
  2142. }")
  2143.  
  2144. ;Lennart Augustsson <augustss@cs.chalmers.se>
  2145. ;says this pattern just makes slower code:
  2146. ;    pushl    %ebp
  2147. ;    addl    $-80,(%esp)
  2148. ;instead of
  2149. ;    leal    -80(%ebp),%eax
  2150. ;    pushl    %eax
  2151. ;
  2152. ;(define_insn ""
  2153. ;  [(set (match_operand:SI 0 "push_operand" "=<")
  2154. ;    (plus:SI (match_operand:SI 1 "general_operand" "%r")
  2155. ;         (match_operand:SI 2 "general_operand" "ri")))]
  2156. ;  ""
  2157. ;  "*
  2158. ;{
  2159. ;  rtx xops[4];
  2160. ;  xops[0] = operands[0];
  2161. ;  xops[1] = operands[1];
  2162. ;  xops[2] = operands[2];
  2163. ;  xops[3] = gen_rtx (MEM, SImode, stack_pointer_rtx);
  2164. ;  output_asm_insn (\"push%z1 %1\", xops);
  2165. ;  output_asm_insn (AS2 (add%z3,%2,%3), xops);
  2166. ;  RET;
  2167. ;}")
  2168.  
  2169. ;; addsi3 is faster, so put this after.
  2170.  
  2171. (define_insn ""
  2172.   [(set (match_operand:SI 0 "register_operand" "=r")
  2173.         (match_operand:QI 1 "address_operand" "p"))]
  2174.   ""
  2175.   "*
  2176. {
  2177.   CC_STATUS_INIT;
  2178.   /* Adding a constant to a register is faster with an add.  */
  2179.   /* ??? can this ever happen? */
  2180.   if (GET_CODE (operands[1]) == PLUS
  2181.       && GET_CODE (XEXP (operands[1], 1)) == CONST_INT
  2182.       && rtx_equal_p (operands[0], XEXP (operands[1], 0)))
  2183.     {
  2184.       operands[1] = XEXP (operands[1], 1);
  2185.  
  2186.       if (operands[1] == const1_rtx)
  2187.         return AS1 (inc%L0,%0);
  2188.  
  2189.       if (operands[1] == constm1_rtx)
  2190.         return AS1 (dec%L0,%0);
  2191.  
  2192.       return AS2 (add%L0,%1,%0);
  2193.     }
  2194.   return AS2 (lea%L0,%a1,%0);
  2195. }")
  2196.  
  2197. ;; The patterns that match these are at the end of this file.
  2198.  
  2199. (define_expand "addxf3"
  2200.   [(set (match_operand:XF 0 "register_operand" "")
  2201.     (plus:XF (match_operand:XF 1 "nonimmediate_operand" "")
  2202.          (match_operand:XF 2 "nonimmediate_operand" "")))]
  2203.   "TARGET_80387"
  2204.   "")
  2205.  
  2206. (define_expand "adddf3"
  2207.   [(set (match_operand:DF 0 "register_operand" "")
  2208.     (plus:DF (match_operand:DF 1 "nonimmediate_operand" "")
  2209.          (match_operand:DF 2 "nonimmediate_operand" "")))]
  2210.   "TARGET_80387"
  2211.   "")
  2212.  
  2213. (define_expand "addsf3"
  2214.   [(set (match_operand:SF 0 "register_operand" "")
  2215.     (plus:SF (match_operand:SF 1 "nonimmediate_operand" "")
  2216.          (match_operand:SF 2 "nonimmediate_operand" "")))]
  2217.   "TARGET_80387"
  2218.   "")
  2219.  
  2220. ;;- subtract instructions
  2221.  
  2222. (define_insn "subdi3"
  2223.   [(set (match_operand:DI 0 "general_operand" "=&r,ro")
  2224.     (minus:DI (match_operand:DI 1 "general_operand" "0,0")
  2225.           (match_operand:DI 2 "general_operand" "o,riF")))]
  2226.   ""
  2227.   "*
  2228. {
  2229.   rtx low[3], high[3];
  2230.  
  2231.   CC_STATUS_INIT;
  2232.  
  2233.   split_di (operands, 3, low, high);
  2234.  
  2235.   if (GET_CODE (low[2]) != CONST_INT || INTVAL (low[2]) != 0)
  2236.     {
  2237.       output_asm_insn (AS2 (sub%L0,%2,%0), low);
  2238.       output_asm_insn (AS2 (sbb%L0,%2,%0), high);
  2239.     }
  2240.   else
  2241.     output_asm_insn (AS2 (sub%L0,%2,%0), high);
  2242.  
  2243.   RET;
  2244. }")
  2245.  
  2246. (define_insn "subsi3"
  2247.   [(set (match_operand:SI 0 "general_operand" "=rm,r")
  2248.     (minus:SI (match_operand:SI 1 "general_operand" "0,0")
  2249.           (match_operand:SI 2 "general_operand" "ri,rm")))]
  2250.   ""
  2251.   "* return AS2 (sub%L0,%2,%0);")
  2252.  
  2253. (define_insn "subhi3"
  2254.   [(set (match_operand:HI 0 "general_operand" "=rm,r")
  2255.     (minus:HI (match_operand:HI 1 "general_operand" "0,0")
  2256.           (match_operand:HI 2 "general_operand" "ri,rm")))]
  2257.   ""
  2258.   "* return AS2 (sub%W0,%2,%0);")
  2259.  
  2260. (define_insn "subqi3"
  2261.   [(set (match_operand:QI 0 "general_operand" "=qm,q")
  2262.     (minus:QI (match_operand:QI 1 "general_operand" "0,0")
  2263.           (match_operand:QI 2 "general_operand" "qn,qmn")))]
  2264.   ""
  2265.   "* return AS2 (sub%B0,%2,%0);")
  2266.  
  2267. ;; The patterns that match these are at the end of this file.
  2268.  
  2269. (define_expand "subxf3"
  2270.   [(set (match_operand:XF 0 "register_operand" "")
  2271.     (minus:XF (match_operand:XF 1 "nonimmediate_operand" "")
  2272.           (match_operand:XF 2 "nonimmediate_operand" "")))]
  2273.   "TARGET_80387"
  2274.   "")
  2275.  
  2276. (define_expand "subdf3"
  2277.   [(set (match_operand:DF 0 "register_operand" "")
  2278.     (minus:DF (match_operand:DF 1 "nonimmediate_operand" "")
  2279.           (match_operand:DF 2 "nonimmediate_operand" "")))]
  2280.   "TARGET_80387"
  2281.   "")
  2282.  
  2283. (define_expand "subsf3"
  2284.   [(set (match_operand:SF 0 "register_operand" "")
  2285.     (minus:SF (match_operand:SF 1 "nonimmediate_operand" "")
  2286.           (match_operand:SF 2 "nonimmediate_operand" "")))]
  2287.   "TARGET_80387"
  2288.   "")
  2289.  
  2290. ;;- multiply instructions
  2291.  
  2292. ;(define_insn "mulqi3"
  2293. ;  [(set (match_operand:QI 0 "general_operand" "=a")
  2294. ;    (mult:QI (match_operand:QI 1 "general_operand" "%0")
  2295. ;         (match_operand:QI 2 "general_operand" "qm")))]
  2296. ;  ""
  2297. ;  "imul%B0 %2,%0")
  2298.  
  2299. (define_insn ""
  2300.   [(set (match_operand:HI 0 "general_operand" "=r")
  2301.     (mult:SI (match_operand:HI 1 "general_operand" "%0")
  2302.          (match_operand:HI 2 "general_operand" "r")))]
  2303.   "GET_CODE (operands[2]) == CONST_INT && INTVAL (operands[2]) == 0x80"
  2304.   "* return AS2 (imul%W0,%2,%0);")
  2305.  
  2306. (define_insn "mulhi3"
  2307.   [(set (match_operand:HI 0 "general_operand" "=r,r")
  2308.     (mult:SI (match_operand:HI 1 "general_operand" "%0,rm")
  2309.          (match_operand:HI 2 "general_operand" "g,i")))]
  2310.   ""
  2311.   "*
  2312. {
  2313.   if (GET_CODE (operands[1]) == REG
  2314.       && REGNO (operands[1]) == REGNO (operands[0])
  2315.       && (GET_CODE (operands[2]) == MEM || GET_CODE (operands[2]) == REG))
  2316.     /* Assembler has weird restrictions.  */
  2317.     return AS2 (imul%W0,%2,%0);
  2318.   return AS3 (imul%W0,%2,%1,%0);
  2319. }")
  2320.  
  2321. (define_insn ""
  2322.   [(set (match_operand:SI 0 "general_operand" "=r")
  2323.     (mult:SI (match_operand:SI 1 "general_operand" "%0")
  2324.          (match_operand:SI 2 "general_operand" "r")))]
  2325.   "GET_CODE (operands[2]) == CONST_INT && INTVAL (operands[2]) == 0x80"
  2326.   "* return AS2 (imul%L0,%2,%0);")
  2327.  
  2328. (define_insn "mulsi3"
  2329.   [(set (match_operand:SI 0 "general_operand" "=r,r")
  2330.     (mult:SI (match_operand:SI 1 "general_operand" "%0,rm")
  2331.          (match_operand:SI 2 "general_operand" "g,i")))]
  2332.   ""
  2333.   "*
  2334. {
  2335.   if (GET_CODE (operands[1]) == REG
  2336.       && REGNO (operands[1]) == REGNO (operands[0])
  2337.       && (GET_CODE (operands[2]) == MEM || GET_CODE (operands[2]) == REG))
  2338.     /* Assembler has weird restrictions.  */
  2339.     return AS2 (imul%L0,%2,%0);
  2340.   return AS3 (imul%L0,%2,%1,%0);
  2341. }")
  2342.  
  2343. (define_insn ""
  2344.   [(set (match_operand:HI 0 "general_operand" "=a")
  2345.     (mult:SI (zero_extend:HI
  2346.           (match_operand:QI 1 "nonimmediate_operand" "%0"))
  2347.          (zero_extend:HI
  2348.           (match_operand:QI 2 "nonimmediate_operand" "qm"))))]
  2349.   ""
  2350.   "mul%B0 %2")
  2351.  
  2352. ;; The patterns that match these are at the end of this file.
  2353.  
  2354. (define_expand "mulxf3"
  2355.   [(set (match_operand:XF 0 "register_operand" "")
  2356.     (mult:XF (match_operand:XF 1 "nonimmediate_operand" "")
  2357.          (match_operand:XF 2 "nonimmediate_operand" "")))]
  2358.   "TARGET_80387"
  2359.   "")
  2360.  
  2361. (define_expand "muldf3"
  2362.   [(set (match_operand:DF 0 "register_operand" "")
  2363.     (mult:DF (match_operand:DF 1 "nonimmediate_operand" "")
  2364.          (match_operand:DF 2 "nonimmediate_operand" "")))]
  2365.   "TARGET_80387"
  2366.   "")
  2367.  
  2368. (define_expand "mulsf3"
  2369.   [(set (match_operand:SF 0 "register_operand" "")
  2370.     (mult:SF (match_operand:SF 1 "nonimmediate_operand" "")
  2371.          (match_operand:SF 2 "nonimmediate_operand" "")))]
  2372.   "TARGET_80387"
  2373.   "")
  2374.  
  2375. ;;- divide instructions
  2376.  
  2377. (define_insn "divqi3"
  2378.   [(set (match_operand:QI 0 "general_operand" "=a")
  2379.     (div:QI (match_operand:HI 1 "general_operand" "0")
  2380.         (match_operand:QI 2 "general_operand" "qm")))]
  2381.   ""
  2382.   "idiv%B0 %2")
  2383.  
  2384. (define_insn "udivqi3"
  2385.   [(set (match_operand:QI 0 "general_operand" "=a")
  2386.     (udiv:QI (match_operand:HI 1 "general_operand" "0")
  2387.          (match_operand:QI 2 "general_operand" "qm")))]
  2388.   ""
  2389.   "div%B0 %2")
  2390.  
  2391. ;; The patterns that match these are at the end of this file.
  2392.  
  2393. (define_expand "divxf3"
  2394.   [(set (match_operand:XF 0 "register_operand" "")
  2395.     (div:XF (match_operand:XF 1 "nonimmediate_operand" "")
  2396.         (match_operand:XF 2 "nonimmediate_operand" "")))]
  2397.   "TARGET_80387"
  2398.   "")
  2399.  
  2400. (define_expand "divdf3"
  2401.   [(set (match_operand:DF 0 "register_operand" "")
  2402.     (div:DF (match_operand:DF 1 "nonimmediate_operand" "")
  2403.         (match_operand:DF 2 "nonimmediate_operand" "")))]
  2404.   "TARGET_80387"
  2405.   "")
  2406.  
  2407. (define_expand "divsf3"
  2408.   [(set (match_operand:SF 0 "register_operand" "")
  2409.     (div:SF (match_operand:SF 1 "nonimmediate_operand" "")
  2410.         (match_operand:SF 2 "nonimmediate_operand" "")))]
  2411.   "TARGET_80387"
  2412.   "")
  2413.  
  2414. ;; Remainder instructions.
  2415.  
  2416. (define_insn "divmodsi4"
  2417.   [(set (match_operand:SI 0 "register_operand" "=a")
  2418.     (div:SI (match_operand:SI 1 "register_operand" "0")
  2419.         (match_operand:SI 2 "general_operand" "rm")))
  2420.    (set (match_operand:SI 3 "register_operand" "=&d")
  2421.     (mod:SI (match_dup 1) (match_dup 2)))]
  2422.   ""
  2423.   "*
  2424. {
  2425. #ifdef INTEL_SYNTAX
  2426.   output_asm_insn (\"cdq\", operands);
  2427. #else
  2428.   output_asm_insn (\"cltd\", operands);
  2429. #endif
  2430.   return AS1 (idiv%L0,%2);
  2431. }")
  2432.  
  2433. (define_insn "divmodhi4"
  2434.   [(set (match_operand:HI 0 "register_operand" "=a")
  2435.     (div:HI (match_operand:HI 1 "register_operand" "0")
  2436.         (match_operand:HI 2 "general_operand" "rm")))
  2437.    (set (match_operand:HI 3 "register_operand" "=&d")
  2438.     (mod:HI (match_dup 1) (match_dup 2)))]
  2439.   ""
  2440.   "cwtd\;idiv%W0 %2")
  2441.  
  2442. ;; ??? Can we make gcc zero extend operand[0]?
  2443. (define_insn "udivmodsi4"
  2444.   [(set (match_operand:SI 0 "register_operand" "=a")
  2445.     (udiv:SI (match_operand:SI 1 "register_operand" "0")
  2446.          (match_operand:SI 2 "general_operand" "rm")))
  2447.    (set (match_operand:SI 3 "register_operand" "=&d")
  2448.     (umod:SI (match_dup 1) (match_dup 2)))]
  2449.   ""
  2450.   "*
  2451. {
  2452.   output_asm_insn (AS2 (xor%L3,%3,%3), operands);
  2453.   return AS1 (div%L0,%2);
  2454. }")
  2455.  
  2456. ;; ??? Can we make gcc zero extend operand[0]?
  2457. (define_insn "udivmodhi4"
  2458.   [(set (match_operand:HI 0 "register_operand" "=a")
  2459.     (udiv:HI (match_operand:HI 1 "register_operand" "0")
  2460.          (match_operand:HI 2 "general_operand" "rm")))
  2461.    (set (match_operand:HI 3 "register_operand" "=&d")
  2462.     (umod:HI (match_dup 1) (match_dup 2)))]
  2463.   ""
  2464.   "*
  2465. {
  2466.   output_asm_insn (AS2 (xor%W0,%3,%3), operands);
  2467.   return AS1 (div%W0,%2);
  2468. }")
  2469.  
  2470. /*
  2471. ;;this should be a valid double division which we may want to add
  2472.  
  2473. (define_insn ""
  2474.   [(set (match_operand:SI 0 "register_operand" "=a")
  2475.     (udiv:DI (match_operand:DI 1 "register_operand" "a")
  2476.          (match_operand:SI 2 "general_operand" "rm")))
  2477.    (set (match_operand:SI 3 "register_operand" "=d")
  2478.     (umod:SI (match_dup 1) (match_dup 2)))]
  2479.   ""
  2480.   "div%L0 %2,%0")
  2481. */
  2482.  
  2483. ;;- and instructions
  2484.  
  2485. ;; On i386,
  2486. ;;            movzbl %bl,%ebx
  2487. ;; is faster than
  2488. ;;            andl $255,%ebx
  2489. ;;
  2490. ;; but if the reg is %eax, then the "andl" is faster.
  2491. ;;
  2492. ;; On i486, the "andl" is always faster than the "movzbl".
  2493. ;;
  2494. ;; On both i386 and i486, a three operand AND is as fast with movzbl or
  2495. ;; movzwl as with andl, if operands[0] != operands[1].
  2496.  
  2497. ;; The `r' in `rm' for operand 3 looks redundant, but it causes
  2498. ;; optional reloads to be generated if op 3 is a pseudo in a stack slot.
  2499.  
  2500. ;; ??? What if we only change one byte of an offsettable memory reference?
  2501. (define_insn "andsi3"
  2502.   [(set (match_operand:SI 0 "general_operand" "=r,r,rm,r")
  2503.     (and:SI (match_operand:SI 1 "general_operand" "%rm,qm,0,0")
  2504.         (match_operand:SI 2 "general_operand" "L,K,ri,rm")))]
  2505.   ""
  2506.   "*
  2507. {
  2508.   if (GET_CODE (operands[2]) == CONST_INT
  2509.       && ! (GET_CODE (operands[0]) == MEM && MEM_VOLATILE_P (operands[0])))
  2510.     {
  2511.       if (INTVAL (operands[2]) == 0xffff && REG_P (operands[0])
  2512.       && (! REG_P (operands[1])
  2513.           || REGNO (operands[0]) != 0 || REGNO (operands[1]) != 0)
  2514.       && (! TARGET_486 || ! rtx_equal_p (operands[0], operands[1])))
  2515.     {
  2516.       /* ??? tege: Should forget CC_STATUS only if we clobber a
  2517.          remembered operand.  Fix that later.  */
  2518.       CC_STATUS_INIT;
  2519. #ifdef INTEL_SYNTAX
  2520.       return AS2 (movzx,%w1,%0);
  2521. #else
  2522.       return AS2 (movz%W0%L0,%w1,%0);
  2523. #endif
  2524.     }
  2525.  
  2526.       if (INTVAL (operands[2]) == 0xff && REG_P (operands[0])
  2527.       && !(REG_P (operands[1]) && NON_QI_REG_P (operands[1]))
  2528.       && (! REG_P (operands[1])
  2529.           || REGNO (operands[0]) != 0 || REGNO (operands[1]) != 0)
  2530.       && (! TARGET_486 || ! rtx_equal_p (operands[0], operands[1])))
  2531.     {
  2532.       /* ??? tege: Should forget CC_STATUS only if we clobber a
  2533.          remembered operand.  Fix that later.  */
  2534.       CC_STATUS_INIT;
  2535. #ifdef INTEL_SYNTAX
  2536.       return AS2 (movzx,%b1,%0);
  2537. #else
  2538.       return AS2 (movz%B0%L0,%b1,%0);
  2539. #endif
  2540.     }
  2541.  
  2542.       if (QI_REG_P (operands[0]) && ~(INTVAL (operands[2]) | 0xff) == 0)
  2543.     {
  2544.       CC_STATUS_INIT;
  2545.  
  2546.       if (INTVAL (operands[2]) == 0xffffff00)
  2547.         {
  2548.           operands[2] = const0_rtx;
  2549.           return AS2 (mov%B0,%2,%b0);
  2550.         }
  2551.  
  2552.       operands[2] = GEN_INT (INTVAL (operands[2]) & 0xff);
  2553.       return AS2 (and%B0,%2,%b0);
  2554.     }
  2555.  
  2556.       if (QI_REG_P (operands[0]) && ~(INTVAL (operands[2]) | 0xff00) == 0)
  2557.     {
  2558.       CC_STATUS_INIT;
  2559.  
  2560.       if (INTVAL (operands[2]) == 0xffff00ff)
  2561.         {
  2562.           operands[2] = const0_rtx;
  2563.           return AS2 (mov%B0,%2,%h0);
  2564.         }
  2565.  
  2566.       operands[2] = GEN_INT ((INTVAL (operands[2]) >> 8) & 0xff);
  2567.       return AS2 (and%B0,%2,%h0);
  2568.     }
  2569.  
  2570.       if (GET_CODE (operands[0]) == MEM && INTVAL (operands[2]) == 0xffff0000)
  2571.         {
  2572.       operands[2] = const0_rtx;
  2573.       return AS2 (mov%W0,%2,%w0);
  2574.     }
  2575.     }
  2576.  
  2577.   return AS2 (and%L0,%2,%0);
  2578. }")
  2579.  
  2580. (define_insn "andhi3"
  2581.   [(set (match_operand:HI 0 "general_operand" "=rm,r")
  2582.     (and:HI (match_operand:HI 1 "general_operand" "%0,0")
  2583.         (match_operand:HI 2 "general_operand" "ri,rm")))]
  2584.   ""
  2585.   "*
  2586. {
  2587.   if (GET_CODE (operands[2]) == CONST_INT
  2588.       && ! (GET_CODE (operands[0]) == MEM && MEM_VOLATILE_P (operands[0])))
  2589.     {
  2590.       /* Can we ignore the upper byte? */
  2591.       if ((! REG_P (operands[0]) || QI_REG_P (operands[0]))
  2592.       && (INTVAL (operands[2]) & 0xff00) == 0xff00)
  2593.     {
  2594.       CC_STATUS_INIT;
  2595.  
  2596.       if ((INTVAL (operands[2]) & 0xff) == 0)
  2597.         {
  2598.           operands[2] = const0_rtx;
  2599.           return AS2 (mov%B0,%2,%b0);
  2600.         }
  2601.  
  2602.       operands[2] = GEN_INT (INTVAL (operands[2]) & 0xff);
  2603.       return AS2 (and%B0,%2,%b0);
  2604.     }
  2605.  
  2606.       /* Can we ignore the lower byte? */
  2607.       /* ??? what about offsettable memory references? */
  2608.       if (QI_REG_P (operands[0]) && (INTVAL (operands[2]) & 0xff) == 0xff)
  2609.     {
  2610.       CC_STATUS_INIT;
  2611.  
  2612.       if ((INTVAL (operands[2]) & 0xff00) == 0)
  2613.         {
  2614.           operands[2] = const0_rtx;
  2615.           return AS2 (mov%B0,%2,%h0);
  2616.         }
  2617.  
  2618.       operands[2] = GEN_INT ((INTVAL (operands[2]) >> 8) & 0xff);
  2619.       return AS2 (and%B0,%2,%h0);
  2620.     }
  2621.     }
  2622.  
  2623.   return AS2 (and%W0,%2,%0);
  2624. }")
  2625.  
  2626. (define_insn "andqi3"
  2627.   [(set (match_operand:QI 0 "general_operand" "=qm,q")
  2628.     (and:QI (match_operand:QI 1 "general_operand" "%0,0")
  2629.         (match_operand:QI 2 "general_operand" "qn,qmn")))]
  2630.   ""
  2631.   "* return AS2 (and%B0,%2,%0);")
  2632.  
  2633. /* I am nervous about these two.. add them later..
  2634. ;I presume this means that we have something in say op0= eax which is small
  2635. ;and we want to and it with memory so we can do this by just an
  2636. ;andb m,%al  and have success.
  2637. (define_insn ""
  2638.   [(set (match_operand:SI 0 "general_operand" "=r")
  2639.     (and:SI (zero_extend:SI
  2640.          (match_operand:HI 1 "nonimmediate_operand" "rm"))
  2641.         (match_operand:SI 2 "general_operand" "0")))]
  2642.   "GET_CODE (operands[2]) == CONST_INT
  2643.    && (unsigned int) INTVAL (operands[2]) < (1 << GET_MODE_BITSIZE (HImode))"
  2644.   "and%W0 %1,%0")
  2645.  
  2646. (define_insn ""
  2647.   [(set (match_operand:SI 0 "general_operand" "=q")
  2648.     (and:SI
  2649.      (zero_extend:SI (match_operand:QI 1 "nonimmediate_operand" "qm"))
  2650.         (match_operand:SI 2 "general_operand" "0")))]
  2651.   "GET_CODE (operands[2]) == CONST_INT
  2652.    && (unsigned int) INTVAL (operands[2]) < (1 << GET_MODE_BITSIZE (QImode))"
  2653.   "and%L0 %1,%0")
  2654.  
  2655. */
  2656.  
  2657. ;;- Bit set (inclusive or) instructions
  2658.  
  2659. ;; ??? What if we only change one byte of an offsettable memory reference?
  2660. (define_insn "iorsi3"
  2661.   [(set (match_operand:SI 0 "general_operand" "=rm,r")
  2662.     (ior:SI (match_operand:SI 1 "general_operand" "%0,0")
  2663.         (match_operand:SI 2 "general_operand" "ri,rm")))]
  2664.   ""
  2665.   "*
  2666. {
  2667.   if (GET_CODE (operands[2]) == CONST_INT
  2668.       && ! (GET_CODE (operands[0]) == MEM && MEM_VOLATILE_P (operands[0])))
  2669.     {
  2670.       if ((! REG_P (operands[0]) || QI_REG_P (operands[0]))
  2671.       && (INTVAL (operands[2]) & ~0xff) == 0)
  2672.     {
  2673.       CC_STATUS_INIT;
  2674.  
  2675.       if (INTVAL (operands[2]) == 0xff)
  2676.         return AS2 (mov%B0,%2,%b0);
  2677.  
  2678.       return AS2 (or%B0,%2,%b0);
  2679.     }
  2680.  
  2681.       if (QI_REG_P (operands[0]) && (INTVAL (operands[2]) & ~0xff00) == 0)
  2682.     {
  2683.       CC_STATUS_INIT;
  2684.       operands[2] = GEN_INT (INTVAL (operands[2]) >> 8);
  2685.  
  2686.       if (INTVAL (operands[2]) == 0xff)
  2687.         return AS2 (mov%B0,%2,%h0);
  2688.  
  2689.       return AS2 (or%B0,%2,%h0);
  2690.     }
  2691.     }
  2692.  
  2693.   return AS2 (or%L0,%2,%0);
  2694. }")
  2695.  
  2696. (define_insn "iorhi3"
  2697.   [(set (match_operand:HI 0 "general_operand" "=rm,r")
  2698.     (ior:HI (match_operand:HI 1 "general_operand" "%0,0")
  2699.         (match_operand:HI 2 "general_operand" "ri,rm")))]
  2700.   ""
  2701.   "*
  2702. {
  2703.   if (GET_CODE (operands[2]) == CONST_INT
  2704.       && ! (GET_CODE (operands[0]) == MEM && MEM_VOLATILE_P (operands[0])))
  2705.     {
  2706.       /* Can we ignore the upper byte? */
  2707.       if ((! REG_P (operands[0]) || QI_REG_P (operands[0]))
  2708.       && (INTVAL (operands[2]) & 0xff00) == 0)
  2709.     {
  2710.       CC_STATUS_INIT;
  2711.       if (INTVAL (operands[2]) & 0xffff0000)
  2712.         operands[2] = GEN_INT (INTVAL (operands[2]) & 0xffff);
  2713.  
  2714.       if (INTVAL (operands[2]) == 0xff)
  2715.         return AS2 (mov%B0,%2,%b0);
  2716.  
  2717.       return AS2 (or%B0,%2,%b0);
  2718.     }
  2719.  
  2720.       /* Can we ignore the lower byte? */
  2721.       /* ??? what about offsettable memory references? */
  2722.       if (QI_REG_P (operands[0])
  2723.       && (INTVAL (operands[2]) & 0xff) == 0)
  2724.     {
  2725.       CC_STATUS_INIT;
  2726.       operands[2] = GEN_INT ((INTVAL (operands[2]) >> 8) & 0xff);
  2727.  
  2728.       if (INTVAL (operands[2]) == 0xff)
  2729.         return AS2 (mov%B0,%2,%h0);
  2730.  
  2731.       return AS2 (or%B0,%2,%h0);
  2732.     }
  2733.     }
  2734.  
  2735.   return AS2 (or%W0,%2,%0);
  2736. }")
  2737.  
  2738. (define_insn "iorqi3"
  2739.   [(set (match_operand:QI 0 "general_operand" "=qm,q")
  2740.     (ior:QI (match_operand:QI 1 "general_operand" "%0,0")
  2741.         (match_operand:QI 2 "general_operand" "qn,qmn")))]
  2742.   ""
  2743.   "* return AS2 (or%B0,%2,%0);")
  2744.  
  2745. ;;- xor instructions
  2746.  
  2747. ;; ??? What if we only change one byte of an offsettable memory reference?
  2748. (define_insn "xorsi3"
  2749.   [(set (match_operand:SI 0 "general_operand" "=rm,r")
  2750.     (xor:SI (match_operand:SI 1 "general_operand" "%0,0")
  2751.         (match_operand:SI 2 "general_operand" "ri,rm")))]
  2752.   ""
  2753.   "*
  2754. {
  2755.   if (GET_CODE (operands[2]) == CONST_INT
  2756.       && ! (GET_CODE (operands[0]) == MEM && MEM_VOLATILE_P (operands[0])))
  2757.     {
  2758.       if ((! REG_P (operands[0]) || QI_REG_P (operands[0]))
  2759.       && (INTVAL (operands[2]) & ~0xff) == 0)
  2760.     {
  2761.       CC_STATUS_INIT;
  2762.  
  2763.       if (INTVAL (operands[2]) == 0xff)
  2764.         return AS1 (not%B0,%b0);
  2765.  
  2766.       return AS2 (xor%B0,%2,%b0);
  2767.     }
  2768.  
  2769.       if (QI_REG_P (operands[0]) && (INTVAL (operands[2]) & ~0xff00) == 0)
  2770.     {
  2771.       CC_STATUS_INIT;
  2772.       operands[2] = GEN_INT (INTVAL (operands[2]) >> 8);
  2773.  
  2774.       if (INTVAL (operands[2]) == 0xff)
  2775.         return AS1 (not%B0,%h0);
  2776.  
  2777.       return AS2 (xor%B0,%2,%h0);
  2778.     }
  2779.     }
  2780.  
  2781.   return AS2 (xor%L0,%2,%0);
  2782. }")
  2783.  
  2784. (define_insn "xorhi3"
  2785.   [(set (match_operand:HI 0 "general_operand" "=rm,r")
  2786.     (xor:HI (match_operand:HI 1 "general_operand" "%0,0")
  2787.         (match_operand:HI 2 "general_operand" "ri,rm")))]
  2788.   ""
  2789.   "*
  2790. {
  2791.   if (GET_CODE (operands[2]) == CONST_INT
  2792.       && ! (GET_CODE (operands[0]) == MEM && MEM_VOLATILE_P (operands[0])))
  2793.     {
  2794.       /* Can we ignore the upper byte? */
  2795.       if ((! REG_P (operands[0]) || QI_REG_P (operands[0]))
  2796.       && (INTVAL (operands[2]) & 0xff00) == 0)
  2797.     {
  2798.       CC_STATUS_INIT;
  2799.       if (INTVAL (operands[2]) & 0xffff0000)
  2800.         operands[2] = GEN_INT (INTVAL (operands[2]) & 0xffff);
  2801.  
  2802.       if (INTVAL (operands[2]) == 0xff)
  2803.         return AS1 (not%B0,%b0);
  2804.  
  2805.       return AS2 (xor%B0,%2,%b0);
  2806.     }
  2807.  
  2808.       /* Can we ignore the lower byte? */
  2809.       /* ??? what about offsettable memory references? */
  2810.       if (QI_REG_P (operands[0])
  2811.       && (INTVAL (operands[2]) & 0xff) == 0)
  2812.     {
  2813.       CC_STATUS_INIT;
  2814.       operands[2] = GEN_INT ((INTVAL (operands[2]) >> 8) & 0xff);
  2815.  
  2816.       if (INTVAL (operands[2]) == 0xff)
  2817.         return AS1 (not%B0,%h0);
  2818.  
  2819.       return AS2 (xor%B0,%2,%h0);
  2820.     }
  2821.     }
  2822.  
  2823.   return AS2 (xor%W0,%2,%0);
  2824. }")
  2825.  
  2826. (define_insn "xorqi3"
  2827.   [(set (match_operand:QI 0 "general_operand" "=qm,q")
  2828.     (xor:QI (match_operand:QI 1 "general_operand" "%0,0")
  2829.         (match_operand:QI 2 "general_operand" "qn,qm")))]
  2830.   ""
  2831.   "* return AS2 (xor%B0,%2,%0);")
  2832.  
  2833. ;;- negation instructions
  2834.  
  2835. (define_insn "negdi2"
  2836.   [(set (match_operand:DI 0 "general_operand" "=&ro")
  2837.     (neg:DI (match_operand:DI 1 "general_operand" "0")))]
  2838.   ""
  2839.   "*
  2840. {
  2841.   rtx xops[2], low[1], high[1];
  2842.  
  2843.   CC_STATUS_INIT;
  2844.  
  2845.   split_di (operands, 1, low, high);
  2846.   xops[0] = const0_rtx;
  2847.   xops[1] = high[0];
  2848.  
  2849.   output_asm_insn (AS1 (neg%L0,%0), low);
  2850.   output_asm_insn (AS2 (adc%L1,%0,%1), xops);
  2851.   output_asm_insn (AS1 (neg%L0,%0), high);
  2852.   RET;
  2853. }")
  2854.  
  2855. (define_insn "negsi2"
  2856.   [(set (match_operand:SI 0 "general_operand" "=rm")
  2857.     (neg:SI (match_operand:SI 1 "general_operand" "0")))]
  2858.   ""
  2859.   "neg%L0 %0")
  2860.  
  2861. (define_insn "neghi2"
  2862.   [(set (match_operand:HI 0 "general_operand" "=rm")
  2863.     (neg:HI (match_operand:HI 1 "general_operand" "0")))]
  2864.   ""
  2865.   "neg%W0 %0")
  2866.  
  2867. (define_insn "negqi2"
  2868.   [(set (match_operand:QI 0 "general_operand" "=qm")
  2869.     (neg:QI (match_operand:QI 1 "general_operand" "0")))]
  2870.   ""
  2871.   "neg%B0 %0")
  2872.  
  2873. (define_insn "negsf2"
  2874.   [(set (match_operand:SF 0 "register_operand" "=f")
  2875.     (neg:SF (match_operand:SF 1 "general_operand" "0")))]
  2876.   "TARGET_80387"
  2877.   "fchs")
  2878.  
  2879. (define_insn "negdf2"
  2880.   [(set (match_operand:DF 0 "register_operand" "=f")
  2881.     (neg:DF (match_operand:DF 1 "general_operand" "0")))]
  2882.   "TARGET_80387"
  2883.   "fchs")
  2884.  
  2885. (define_insn ""
  2886.   [(set (match_operand:DF 0 "register_operand" "=f")
  2887.     (neg:DF (float_extend:DF (match_operand:SF 1 "general_operand" "0"))))]
  2888.   "TARGET_80387"
  2889.   "fchs")
  2890.  
  2891. (define_insn "negxf2"
  2892.   [(set (match_operand:XF 0 "register_operand" "=f")
  2893.     (neg:XF (match_operand:XF 1 "general_operand" "0")))]
  2894.   "TARGET_80387"
  2895.   "fchs")
  2896.  
  2897. (define_insn ""
  2898.   [(set (match_operand:XF 0 "register_operand" "=f")
  2899.     (neg:XF (float_extend:XF (match_operand:DF 1 "general_operand" "0"))))]
  2900.   "TARGET_80387"
  2901.   "fchs")
  2902.  
  2903. ;; Absolute value instructions
  2904.  
  2905. (define_insn "abssf2"
  2906.   [(set (match_operand:SF 0 "register_operand" "=f")
  2907.     (abs:SF (match_operand:SF 1 "general_operand" "0")))]
  2908.   "TARGET_80387"
  2909.   "fabs")
  2910.  
  2911. (define_insn "absdf2"
  2912.   [(set (match_operand:DF 0 "register_operand" "=f")
  2913.     (abs:DF (match_operand:DF 1 "general_operand" "0")))]
  2914.   "TARGET_80387"
  2915.   "fabs")
  2916.  
  2917. (define_insn ""
  2918.   [(set (match_operand:DF 0 "register_operand" "=f")
  2919.     (abs:DF (float_extend:DF (match_operand:SF 1 "general_operand" "0"))))]
  2920.   "TARGET_80387"
  2921.   "fabs")
  2922.  
  2923. (define_insn "absxf2"
  2924.   [(set (match_operand:XF 0 "register_operand" "=f")
  2925.     (abs:XF (match_operand:XF 1 "general_operand" "0")))]
  2926.   "TARGET_80387"
  2927.   "fabs")
  2928.  
  2929. (define_insn ""
  2930.   [(set (match_operand:XF 0 "register_operand" "=f")
  2931.     (abs:XF (float_extend:XF (match_operand:DF 1 "general_operand" "0"))))]
  2932.   "TARGET_80387"
  2933.   "fabs")
  2934.  
  2935. (define_insn "sqrtsf2"
  2936.   [(set (match_operand:SF 0 "register_operand" "=f")
  2937.     (sqrt:SF (match_operand:SF 1 "general_operand" "0")))]
  2938.   "TARGET_80387 && (TARGET_IEEE_FP || flag_fast_math)"
  2939.   "fsqrt")
  2940.  
  2941. (define_insn "sqrtdf2"
  2942.   [(set (match_operand:DF 0 "register_operand" "=f")
  2943.     (sqrt:DF (match_operand:DF 1 "general_operand" "0")))]
  2944.   "TARGET_80387 && (TARGET_IEEE_FP || flag_fast_math)"
  2945.   "fsqrt")
  2946.  
  2947. (define_insn ""
  2948.   [(set (match_operand:DF 0 "register_operand" "=f")
  2949.     (sqrt:DF (float_extend:DF
  2950.           (match_operand:SF 1 "general_operand" "0"))))]
  2951.   "TARGET_80387 && (TARGET_IEEE_FP || flag_fast_math)"
  2952.   "fsqrt")
  2953.  
  2954. (define_insn "sqrtxf2"
  2955.   [(set (match_operand:XF 0 "register_operand" "=f")
  2956.     (sqrt:XF (match_operand:XF 1 "general_operand" "0")))]
  2957.   "TARGET_80387 && (TARGET_IEEE_FP || flag_fast_math)"
  2958.   "fsqrt")
  2959.  
  2960. (define_insn ""
  2961.   [(set (match_operand:XF 0 "register_operand" "=f")
  2962.     (sqrt:XF (float_extend:XF
  2963.           (match_operand:DF 1 "general_operand" "0"))))]
  2964.   "TARGET_80387 && (TARGET_IEEE_FP || flag_fast_math)"
  2965.   "fsqrt")
  2966.  
  2967. (define_insn ""
  2968.   [(set (match_operand:XF 0 "register_operand" "=f")
  2969.     (sqrt:XF (float_extend:XF
  2970.           (match_operand:SF 1 "general_operand" "0"))))]
  2971.   "TARGET_80387 && (TARGET_IEEE_FP || flag_fast_math)"
  2972.   "fsqrt")
  2973.  
  2974. (define_insn "sindf2"
  2975.   [(set (match_operand:DF 0 "register_operand" "=f")
  2976.     (unspec:DF [(match_operand:DF 1 "register_operand" "0")] 1))]
  2977.   "TARGET_80387 && (TARGET_IEEE_FP || flag_fast_math)"
  2978.   "fsin")
  2979.  
  2980. (define_insn "sinsf2"
  2981.   [(set (match_operand:SF 0 "register_operand" "=f")
  2982.     (unspec:SF [(match_operand:SF 1 "register_operand" "0")] 1))]
  2983.   "TARGET_80387 && (TARGET_IEEE_FP || flag_fast_math)"
  2984.   "fsin")
  2985.  
  2986. (define_insn ""
  2987.   [(set (match_operand:DF 0 "register_operand" "=f")
  2988.     (unspec:DF [(float_extend:DF
  2989.              (match_operand:SF 1 "register_operand" "0"))] 1))]
  2990.   "TARGET_80387 && (TARGET_IEEE_FP || flag_fast_math)"
  2991.   "fsin")
  2992.  
  2993. (define_insn "cosdf2"
  2994.   [(set (match_operand:DF 0 "register_operand" "=f")
  2995.     (unspec:DF [(match_operand:DF 1 "register_operand" "0")] 2))]
  2996.   "TARGET_80387 && (TARGET_IEEE_FP || flag_fast_math)"
  2997.   "fcos")
  2998.  
  2999. (define_insn "cossf2"
  3000.   [(set (match_operand:SF 0 "register_operand" "=f")
  3001.     (unspec:SF [(match_operand:SF 1 "register_operand" "0")] 2))]
  3002.   "TARGET_80387 && (TARGET_IEEE_FP || flag_fast_math)"
  3003.   "fcos")
  3004.  
  3005. (define_insn ""
  3006.   [(set (match_operand:DF 0 "register_operand" "=f")
  3007.     (unspec:DF [(float_extend:DF
  3008.              (match_operand:SF 1 "register_operand" "0"))] 2))]
  3009.   "TARGET_80387 && (TARGET_IEEE_FP || flag_fast_math)"
  3010.   "fcos")
  3011.  
  3012. ;;- one complement instructions
  3013.  
  3014. (define_insn "one_cmplsi2"
  3015.   [(set (match_operand:SI 0 "general_operand" "=rm")
  3016.     (not:SI (match_operand:SI 1 "general_operand" "0")))]
  3017.   ""
  3018.   "not%L0 %0")
  3019.  
  3020. (define_insn "one_cmplhi2"
  3021.   [(set (match_operand:HI 0 "general_operand" "=rm")
  3022.     (not:HI (match_operand:HI 1 "general_operand" "0")))]
  3023.   ""
  3024.   "not%W0 %0")
  3025.  
  3026. (define_insn "one_cmplqi2"
  3027.   [(set (match_operand:QI 0 "general_operand" "=qm")
  3028.     (not:QI (match_operand:QI 1 "general_operand" "0")))]
  3029.   ""
  3030.   "not%B0 %0")
  3031.  
  3032. ;;- arithmetic shift instructions
  3033.  
  3034. ;; DImode shifts are implemented using the i386 "shift double" opcode,
  3035. ;; which is written as "sh[lr]d[lw] imm,reg,reg/mem".  If the shift count
  3036. ;; is variable, then the count is in %cl and the "imm" operand is dropped
  3037. ;; from the assembler input.
  3038.  
  3039. ;; This instruction shifts the target reg/mem as usual, but instead of
  3040. ;; shifting in zeros, bits are shifted in from reg operand.  If the insn
  3041. ;; is a left shift double, bits are taken from the high order bits of
  3042. ;; reg, else if the insn is a shift right double, bits are taken from the
  3043. ;; low order bits of reg.  So if %eax is "1234" and %edx is "5678",
  3044. ;; "shldl $8,%edx,%eax" leaves %edx unchanged and sets %eax to "2345".
  3045.  
  3046. ;; Since sh[lr]d does not change the `reg' operand, that is done
  3047. ;; separately, making all shifts emit pairs of shift double and normal
  3048. ;; shift.  Since sh[lr]d does not shift more than 31 bits, and we wish to
  3049. ;; support a 63 bit shift, each shift where the count is in a reg expands
  3050. ;; to three pairs.  If the overall shift is by N bits, then the first two
  3051. ;; pairs shift by N / 2 and the last pair by N & 1.
  3052.  
  3053. ;; If the shift count is a constant, we need never emit more than one
  3054. ;; shift pair, instead using moves and sign extension for counts greater
  3055. ;; than 31.
  3056.  
  3057. (define_expand "ashldi3"
  3058.   [(set (match_operand:DI 0 "register_operand" "")
  3059.     (ashift:DI (match_operand:DI 1 "register_operand" "")
  3060.            (match_operand:QI 2 "nonmemory_operand" "")))]
  3061.   ""
  3062.   "
  3063. {
  3064.   if (GET_CODE (operands[2]) != CONST_INT
  3065.       || ! CONST_OK_FOR_LETTER_P (INTVAL (operands[2]), 'J'))
  3066.     {
  3067.       operands[2] = copy_to_mode_reg (QImode, operands[2]);
  3068.       emit_insn (gen_ashldi3_non_const_int (operands[0], operands[1],
  3069.                         operands[2]));
  3070.     }
  3071.   else
  3072.     emit_insn (gen_ashldi3_const_int (operands[0], operands[1], operands[2]));
  3073.  
  3074.   DONE;
  3075. }")
  3076.  
  3077. (define_insn "ashldi3_const_int"
  3078.   [(set (match_operand:DI 0 "register_operand" "=&r")
  3079.     (ashift:DI (match_operand:DI 1 "register_operand" "0")
  3080.            (match_operand:QI 2 "const_int_operand" "J")))]
  3081.   ""
  3082.   "*
  3083. {
  3084.   rtx xops[4], low[1], high[1];
  3085.  
  3086.   CC_STATUS_INIT;
  3087.  
  3088.   split_di (operands, 1, low, high);
  3089.   xops[0] = operands[2];
  3090.   xops[1] = const1_rtx;
  3091.   xops[2] = low[0];
  3092.   xops[3] = high[0];
  3093.  
  3094.   if (INTVAL (xops[0]) > 31)
  3095.     {
  3096.       output_asm_insn (AS2 (mov%L3,%2,%3), xops);    /* Fast shift by 32 */
  3097.       output_asm_insn (AS2 (xor%L2,%2,%2), xops);
  3098.  
  3099.       if (INTVAL (xops[0]) > 32)
  3100.         {
  3101.       xops[0] = GEN_INT (INTVAL (xops[0]) - 32);
  3102.       output_asm_insn (AS2 (sal%L3,%0,%3), xops); /* Remaining shift */
  3103.     }
  3104.     }
  3105.   else
  3106.     {
  3107.       output_asm_insn (AS3 (shld%L3,%0,%2,%3), xops);
  3108.       output_asm_insn (AS2 (sal%L2,%0,%2), xops);
  3109.     }
  3110.   RET;
  3111. }")
  3112.  
  3113. (define_insn "ashldi3_non_const_int"
  3114.   [(set (match_operand:DI 0 "register_operand" "=&r")
  3115.     (ashift:DI (match_operand:DI 1 "register_operand" "0")
  3116.            (match_operand:QI 2 "register_operand" "c")))
  3117.    (clobber (match_dup 2))]
  3118.   ""
  3119.   "*
  3120. {
  3121.   rtx xops[4], low[1], high[1];
  3122.  
  3123.   CC_STATUS_INIT;
  3124.  
  3125.   split_di (operands, 1, low, high);
  3126.   xops[0] = operands[2];
  3127.   xops[1] = const1_rtx;
  3128.   xops[2] = low[0];
  3129.   xops[3] = high[0];
  3130.  
  3131.   output_asm_insn (AS2 (ror%B0,%1,%0), xops);    /* shift count / 2 */
  3132.  
  3133.   output_asm_insn (AS3_SHIFT_DOUBLE (shld%L3,%0,%2,%3), xops);
  3134.   output_asm_insn (AS2 (sal%L2,%0,%2), xops);
  3135.   output_asm_insn (AS3_SHIFT_DOUBLE (shld%L3,%0,%2,%3), xops);
  3136.   output_asm_insn (AS2 (sal%L2,%0,%2), xops);
  3137.  
  3138.   xops[1] = GEN_INT (7);            /* shift count & 1 */
  3139.  
  3140.   output_asm_insn (AS2 (shr%B0,%1,%0), xops);
  3141.  
  3142.   output_asm_insn (AS3_SHIFT_DOUBLE (shld%L3,%0,%2,%3), xops);
  3143.   output_asm_insn (AS2 (sal%L2,%0,%2), xops);
  3144.  
  3145.   RET;
  3146. }")
  3147.  
  3148. ;; On i386 and i486, "addl reg,reg" is faster than "sall $1,reg"
  3149. ;; On i486, movl/sall appears slightly faster than leal, but the leal
  3150. ;; is smaller - use leal for now unless the shift count is 1.
  3151.  
  3152. (define_insn "ashlsi3"
  3153.   [(set (match_operand:SI 0 "general_operand" "=r,rm")
  3154.     (ashift:SI (match_operand:SI 1 "general_operand" "r,0")
  3155.            (match_operand:SI 2 "nonmemory_operand" "M,cI")))]
  3156.   ""
  3157.   "*
  3158. {
  3159.   if (REG_P (operands[0]) && REGNO (operands[0]) != REGNO (operands[1]))
  3160.     {
  3161.       if (TARGET_486 && INTVAL (operands[2]) == 1)
  3162.     {
  3163.       output_asm_insn (AS2 (mov%L0,%1,%0), operands);
  3164.       return AS2 (add%L0,%1,%0);
  3165.     }
  3166.       else
  3167.         {
  3168.           CC_STATUS_INIT;
  3169.  
  3170.       if (operands[1] == stack_pointer_rtx)
  3171.         {
  3172.           output_asm_insn (AS2 (mov%L0,%1,%0), operands);
  3173.           operands[1] = operands[0];
  3174.         }
  3175.           operands[1] = gen_rtx (MULT, SImode, operands[1],
  3176.                  GEN_INT (1 << INTVAL (operands[2])));
  3177.       return AS2 (lea%L0,%a1,%0);
  3178.     }
  3179.     }
  3180.  
  3181.   if (REG_P (operands[2]))
  3182.     return AS2 (sal%L0,%b2,%0);
  3183.  
  3184.   if (REG_P (operands[0]) && operands[2] == const1_rtx)
  3185.     return AS2 (add%L0,%0,%0);
  3186.  
  3187.   return AS2 (sal%L0,%2,%0);
  3188. }")
  3189.  
  3190. (define_insn "ashlhi3"
  3191.   [(set (match_operand:HI 0 "general_operand" "=rm")
  3192.     (ashift:HI (match_operand:HI 1 "general_operand" "0")
  3193.            (match_operand:HI 2 "nonmemory_operand" "cI")))]
  3194.   ""
  3195.   "*
  3196. {
  3197.   if (REG_P (operands[2]))
  3198.     return AS2 (sal%W0,%b2,%0);
  3199.  
  3200.   if (REG_P (operands[0]) && operands[2] == const1_rtx)
  3201.     return AS2 (add%W0,%0,%0);
  3202.  
  3203.   return AS2 (sal%W0,%2,%0);
  3204. }")
  3205.  
  3206. (define_insn "ashlqi3"
  3207.   [(set (match_operand:QI 0 "general_operand" "=qm")
  3208.     (ashift:QI (match_operand:QI 1 "general_operand" "0")
  3209.            (match_operand:QI 2 "nonmemory_operand" "cI")))]
  3210.   ""
  3211.   "*
  3212. {
  3213.   if (REG_P (operands[2]))
  3214.     return AS2 (sal%B0,%b2,%0);
  3215.  
  3216.   if (REG_P (operands[0]) && operands[2] == const1_rtx)
  3217.     return AS2 (add%B0,%0,%0);
  3218.  
  3219.   return AS2 (sal%B0,%2,%0);
  3220. }")
  3221.  
  3222. ;; See comment above `ashldi3' about how this works.
  3223.  
  3224. (define_expand "ashrdi3"
  3225.   [(set (match_operand:DI 0 "register_operand" "")
  3226.     (ashiftrt:DI (match_operand:DI 1 "register_operand" "")
  3227.              (match_operand:QI 2 "nonmemory_operand" "")))]
  3228.   ""
  3229.   "
  3230. {
  3231.   if (GET_CODE (operands[2]) != CONST_INT
  3232.       || ! CONST_OK_FOR_LETTER_P (INTVAL (operands[2]), 'J'))
  3233.     {
  3234.       operands[2] = copy_to_mode_reg (QImode, operands[2]);
  3235.       emit_insn (gen_ashrdi3_non_const_int (operands[0], operands[1],
  3236.                         operands[2]));
  3237.     }
  3238.   else
  3239.     emit_insn (gen_ashrdi3_const_int (operands[0], operands[1], operands[2]));
  3240.  
  3241.   DONE;
  3242. }")
  3243.  
  3244. (define_insn "ashrdi3_const_int"
  3245.   [(set (match_operand:DI 0 "register_operand" "=&r")
  3246.     (ashiftrt:DI (match_operand:DI 1 "register_operand" "0")
  3247.              (match_operand:QI 2 "const_int_operand" "J")))]
  3248.   ""
  3249.   "*
  3250. {
  3251.   rtx xops[4], low[1], high[1];
  3252.  
  3253.   CC_STATUS_INIT;
  3254.  
  3255.   split_di (operands, 1, low, high);
  3256.   xops[0] = operands[2];
  3257.   xops[1] = const1_rtx;
  3258.   xops[2] = low[0];
  3259.   xops[3] = high[0];
  3260.  
  3261.   if (INTVAL (xops[0]) > 31)
  3262.     {
  3263.       xops[1] = GEN_INT (31);
  3264.       output_asm_insn (AS2 (mov%L2,%3,%2), xops);
  3265.       output_asm_insn (AS2 (sar%L3,%1,%3), xops);    /* shift by 32 */
  3266.  
  3267.       if (INTVAL (xops[0]) > 32)
  3268.         {
  3269.       xops[0] = GEN_INT (INTVAL (xops[0]) - 32);
  3270.       output_asm_insn (AS2 (sar%L2,%0,%2), xops); /* Remaining shift */
  3271.     }
  3272.     }
  3273.   else
  3274.     {
  3275.       output_asm_insn (AS3 (shrd%L2,%0,%3,%2), xops);
  3276.       output_asm_insn (AS2 (sar%L3,%0,%3), xops);
  3277.     }
  3278.  
  3279.   RET;
  3280. }")
  3281.  
  3282. (define_insn "ashrdi3_non_const_int"
  3283.   [(set (match_operand:DI 0 "register_operand" "=&r")
  3284.     (ashiftrt:DI (match_operand:DI 1 "register_operand" "0")
  3285.              (match_operand:QI 2 "register_operand" "c")))
  3286.    (clobber (match_dup 2))]
  3287.   ""
  3288.   "*
  3289. {
  3290.   rtx xops[4], low[1], high[1];
  3291.  
  3292.   CC_STATUS_INIT;
  3293.  
  3294.   split_di (operands, 1, low, high);
  3295.   xops[0] = operands[2];
  3296.   xops[1] = const1_rtx;
  3297.   xops[2] = low[0];
  3298.   xops[3] = high[0];
  3299.  
  3300.   output_asm_insn (AS2 (ror%B0,%1,%0), xops);    /* shift count / 2 */
  3301.  
  3302.   output_asm_insn (AS3_SHIFT_DOUBLE (shrd%L2,%0,%3,%2), xops);
  3303.   output_asm_insn (AS2 (sar%L3,%0,%3), xops);
  3304.   output_asm_insn (AS3_SHIFT_DOUBLE (shrd%L2,%0,%3,%2), xops);
  3305.   output_asm_insn (AS2 (sar%L3,%0,%3), xops);
  3306.  
  3307.   xops[1] = GEN_INT (7);            /* shift count & 1 */
  3308.  
  3309.   output_asm_insn (AS2 (shr%B0,%1,%0), xops);
  3310.  
  3311.   output_asm_insn (AS3_SHIFT_DOUBLE (shrd%L2,%0,%3,%2), xops);
  3312.   output_asm_insn (AS2 (sar%L3,%0,%3), xops);
  3313.  
  3314.   RET;
  3315. }")
  3316.  
  3317. (define_insn "ashrsi3"
  3318.   [(set (match_operand:SI 0 "general_operand" "=rm")
  3319.     (ashiftrt:SI (match_operand:SI 1 "general_operand" "0")
  3320.              (match_operand:SI 2 "nonmemory_operand" "cI")))]
  3321.   ""
  3322.   "*
  3323. {
  3324.   if (REG_P (operands[2]))
  3325.     return AS2 (sar%L0,%b2,%0);
  3326.   else
  3327.     return AS2 (sar%L0,%2,%0);
  3328. }")
  3329.  
  3330. (define_insn "ashrhi3"
  3331.   [(set (match_operand:HI 0 "general_operand" "=rm")
  3332.     (ashiftrt:HI (match_operand:HI 1 "general_operand" "0")
  3333.              (match_operand:HI 2 "nonmemory_operand" "cI")))]
  3334.   ""
  3335.   "*
  3336. {
  3337.   if (REG_P (operands[2]))
  3338.     return AS2 (sar%W0,%b2,%0);
  3339.   else
  3340.     return AS2 (sar%W0,%2,%0);
  3341. }")
  3342.  
  3343. (define_insn "ashrqi3"
  3344.   [(set (match_operand:QI 0 "general_operand" "=qm")
  3345.     (ashiftrt:QI (match_operand:QI 1 "general_operand" "0")
  3346.              (match_operand:QI 2 "nonmemory_operand" "cI")))]
  3347.   ""
  3348.   "*
  3349. {
  3350.   if (REG_P (operands[2]))
  3351.     return AS2 (sar%B0,%b2,%0);
  3352.   else
  3353.     return AS2 (sar%B0,%2,%0);
  3354. }")
  3355.  
  3356. ;;- logical shift instructions
  3357.  
  3358. ;; See comment above `ashldi3' about how this works.
  3359.  
  3360. (define_expand "lshrdi3"
  3361.   [(set (match_operand:DI 0 "register_operand" "")
  3362.     (lshiftrt:DI (match_operand:DI 1 "register_operand" "")
  3363.              (match_operand:QI 2 "nonmemory_operand" "")))]
  3364.   ""
  3365.   "
  3366. {
  3367.   if (GET_CODE (operands[2]) != CONST_INT
  3368.       || ! CONST_OK_FOR_LETTER_P (INTVAL (operands[2]), 'J'))
  3369.     {
  3370.       operands[2] = copy_to_mode_reg (QImode, operands[2]);
  3371.       emit_insn (gen_lshrdi3_non_const_int (operands[0], operands[1],
  3372.                         operands[2]));
  3373.     }
  3374.   else
  3375.     emit_insn (gen_lshrdi3_const_int (operands[0], operands[1], operands[2]));
  3376.  
  3377.   DONE;
  3378. }")
  3379.  
  3380. (define_insn "lshrdi3_const_int"
  3381.   [(set (match_operand:DI 0 "register_operand" "=&r")
  3382.     (lshiftrt:DI (match_operand:DI 1 "register_operand" "0")
  3383.              (match_operand:QI 2 "const_int_operand" "J")))]
  3384.   ""
  3385.   "*
  3386. {
  3387.   rtx xops[4], low[1], high[1];
  3388.  
  3389.   CC_STATUS_INIT;
  3390.  
  3391.   split_di (operands, 1, low, high);
  3392.   xops[0] = operands[2];
  3393.   xops[1] = const1_rtx;
  3394.   xops[2] = low[0];
  3395.   xops[3] = high[0];
  3396.  
  3397.   if (INTVAL (xops[0]) > 31)
  3398.     {
  3399.       output_asm_insn (AS2 (mov%L2,%3,%2), xops);    /* Fast shift by 32 */
  3400.       output_asm_insn (AS2 (xor%L3,%3,%3), xops);
  3401.  
  3402.       if (INTVAL (xops[0]) > 32)
  3403.         {
  3404.       xops[0] = GEN_INT (INTVAL (xops[0]) - 32);
  3405.       output_asm_insn (AS2 (shr%L2,%0,%2), xops); /* Remaining shift */
  3406.     }
  3407.     }
  3408.   else
  3409.     {
  3410.       output_asm_insn (AS3 (shrd%L2,%0,%3,%2), xops);
  3411.       output_asm_insn (AS2 (shr%L3,%0,%3), xops);
  3412.     }
  3413.  
  3414.   RET;
  3415. }")
  3416.  
  3417. (define_insn "lshrdi3_non_const_int"
  3418.   [(set (match_operand:DI 0 "register_operand" "=&r")
  3419.     (lshiftrt:DI (match_operand:DI 1 "register_operand" "0")
  3420.              (match_operand:QI 2 "register_operand" "c")))
  3421.    (clobber (match_dup 2))]
  3422.   ""
  3423.   "*
  3424. {
  3425.   rtx xops[4], low[1], high[1];
  3426.  
  3427.   CC_STATUS_INIT;
  3428.  
  3429.   split_di (operands, 1, low, high);
  3430.   xops[0] = operands[2];
  3431.   xops[1] = const1_rtx;
  3432.   xops[2] = low[0];
  3433.   xops[3] = high[0];
  3434.  
  3435.   output_asm_insn (AS2 (ror%B0,%1,%0), xops);    /* shift count / 2 */
  3436.  
  3437.   output_asm_insn (AS3_SHIFT_DOUBLE (shrd%L2,%0,%3,%2), xops);
  3438.   output_asm_insn (AS2 (shr%L3,%0,%3), xops);
  3439.   output_asm_insn (AS3_SHIFT_DOUBLE (shrd%L2,%0,%3,%2), xops);
  3440.   output_asm_insn (AS2 (shr%L3,%0,%3), xops);
  3441.  
  3442.   xops[1] = GEN_INT (7);            /* shift count & 1 */
  3443.  
  3444.   output_asm_insn (AS2 (shr%B0,%1,%0), xops);
  3445.  
  3446.   output_asm_insn (AS3_SHIFT_DOUBLE (shrd%L2,%0,%3,%2), xops);
  3447.   output_asm_insn (AS2 (shr%L3,%0,%3), xops);
  3448.  
  3449.   RET;
  3450. }")
  3451.  
  3452. (define_insn "lshrsi3"
  3453.   [(set (match_operand:SI 0 "general_operand" "=rm")
  3454.     (lshiftrt:SI (match_operand:SI 1 "general_operand" "0")
  3455.              (match_operand:SI 2 "nonmemory_operand" "cI")))]
  3456.   ""
  3457.   "*
  3458. {
  3459.   if (REG_P (operands[2]))
  3460.     return AS2 (shr%L0,%b2,%0);
  3461.   else
  3462.     return AS2 (shr%L0,%2,%1);
  3463. }")
  3464.  
  3465. (define_insn "lshrhi3"
  3466.   [(set (match_operand:HI 0 "general_operand" "=rm")
  3467.     (lshiftrt:HI (match_operand:HI 1 "general_operand" "0")
  3468.              (match_operand:HI 2 "nonmemory_operand" "cI")))]
  3469.   ""
  3470.   "*
  3471. {
  3472.   if (REG_P (operands[2]))
  3473.     return AS2 (shr%W0,%b2,%0);
  3474.   else
  3475.     return AS2 (shr%W0,%2,%0);
  3476. }")
  3477.  
  3478. (define_insn "lshrqi3"
  3479.   [(set (match_operand:QI 0 "general_operand" "=qm")
  3480.     (lshiftrt:QI (match_operand:QI 1 "general_operand" "0")
  3481.              (match_operand:QI 2 "nonmemory_operand" "cI")))]
  3482.   ""
  3483.   "*
  3484. {
  3485.   if (REG_P (operands[2]))
  3486.     return AS2 (shr%B0,%b2,%0);
  3487.   else
  3488.     return AS2 (shr%B0,%2,%0);
  3489. }")
  3490.  
  3491. ;;- rotate instructions
  3492.  
  3493. (define_insn "rotlsi3"
  3494.   [(set (match_operand:SI 0 "general_operand" "=rm")
  3495.     (rotate:SI (match_operand:SI 1 "general_operand" "0")
  3496.            (match_operand:SI 2 "nonmemory_operand" "cI")))]
  3497.   ""
  3498.   "*
  3499. {
  3500.   if (REG_P (operands[2]))
  3501.     return AS2 (rol%L0,%b2,%0);
  3502.   else
  3503.     return AS2 (rol%L0,%2,%0);
  3504. }")
  3505.  
  3506. (define_insn "rotlhi3"
  3507.   [(set (match_operand:HI 0 "general_operand" "=rm")
  3508.     (rotate:HI (match_operand:HI 1 "general_operand" "0")
  3509.            (match_operand:HI 2 "nonmemory_operand" "cI")))]
  3510.   ""
  3511.   "*
  3512. {
  3513.   if (REG_P (operands[2]))
  3514.     return AS2 (rol%W0,%b2,%0);
  3515.   else
  3516.     return AS2 (rol%W0,%2,%0);
  3517. }")
  3518.  
  3519. (define_insn "rotlqi3"
  3520.   [(set (match_operand:QI 0 "general_operand" "=qm")
  3521.     (rotate:QI (match_operand:QI 1 "general_operand" "0")
  3522.            (match_operand:QI 2 "nonmemory_operand" "cI")))]
  3523.   ""
  3524.   "*
  3525. {
  3526.   if (REG_P (operands[2]))
  3527.     return AS2 (rol%B0,%b2,%0);
  3528.   else
  3529.     return AS2 (rol%B0,%2,%0);
  3530. }")
  3531.  
  3532. (define_insn "rotrsi3"
  3533.   [(set (match_operand:SI 0 "general_operand" "=rm")
  3534.     (rotatert:SI (match_operand:SI 1 "general_operand" "0")
  3535.              (match_operand:SI 2 "nonmemory_operand" "cI")))]
  3536.   ""
  3537.   "*
  3538. {
  3539.   if (REG_P (operands[2]))
  3540.     return AS2 (ror%L0,%b2,%0);
  3541.   else
  3542.     return AS2 (ror%L0,%2,%0);
  3543. }")
  3544.  
  3545. (define_insn "rotrhi3"
  3546.   [(set (match_operand:HI 0 "general_operand" "=rm")
  3547.     (rotatert:HI (match_operand:HI 1 "general_operand" "0")
  3548.              (match_operand:HI 2 "nonmemory_operand" "cI")))]
  3549.   ""
  3550.   "*
  3551. {
  3552.   if (REG_P (operands[2]))
  3553.     return AS2 (ror%W0,%b2,%0);
  3554.   else
  3555.     return AS2 (ror%W0,%2,%0);
  3556. }")
  3557.  
  3558. (define_insn "rotrqi3"
  3559.   [(set (match_operand:QI 0 "general_operand" "=qm")
  3560.     (rotatert:QI (match_operand:QI 1 "general_operand" "0")
  3561.              (match_operand:QI 2 "nonmemory_operand" "cI")))]
  3562.   ""
  3563.   "*
  3564. {
  3565.   if (REG_P (operands[2]))
  3566.     return AS2 (ror%B0,%b2,%0);
  3567.   else
  3568.     return AS2 (ror%B0,%2,%0);
  3569. }")
  3570.  
  3571. /*
  3572. ;; This usually looses.  But try a define_expand to recognize a few case
  3573. ;; we can do efficiently, such as accessing the "high" QImode registers,
  3574. ;; %ah, %bh, %ch, %dh.
  3575. (define_insn "insv"
  3576.   [(set (zero_extract:SI (match_operand:SI 0 "register_operand" "+&r")
  3577.              (match_operand:SI 1 "general_operand" "i")
  3578.              (match_operand:SI 2 "general_operand" "i"))
  3579.     (match_operand:SI 3 "general_operand" "ri"))]
  3580.   ""
  3581.   "*
  3582. {
  3583.   if (INTVAL (operands[1]) + INTVAL (operands[2]) > GET_MODE_BITSIZE (SImode))
  3584.     abort ();
  3585.   if (GET_CODE (operands[3]) == CONST_INT)
  3586.     {
  3587.       unsigned int mask = (1 << INTVAL (operands[1])) - 1; 
  3588.       operands[1] = GEN_INT (~(mask << INTVAL (operands[2])));
  3589.       output_asm_insn (AS2 (and%L0,%1,%0), operands);
  3590.       operands[3] = GEN_INT (INTVAL (operands[3]) << INTVAL (operands[2]));
  3591.       output_asm_insn (AS2 (or%L0,%3,%0), operands);
  3592.     }
  3593.   else
  3594.     {
  3595.       operands[0] = gen_rtx (REG, SImode, REGNO (operands[0]));
  3596.       if (INTVAL (operands[2]))
  3597.     output_asm_insn (AS2 (ror%L0,%2,%0), operands);
  3598.       output_asm_insn (AS3 (shrd%L0,%1,%3,%0), operands);
  3599.       operands[2] = GEN_INT (BITS_PER_WORD
  3600.                  - INTVAL (operands[1]) - INTVAL (operands[2]));
  3601.       if (INTVAL (operands[2]))
  3602.     output_asm_insn (AS2 (ror%L0,%2,%0), operands);
  3603.     }
  3604.   RET;
  3605. }")
  3606. */
  3607. /*
  3608. ;; ??? There are problems with the mode of operand[3].  The point of this
  3609. ;; is to represent an HImode move to a "high byte" register.
  3610.  
  3611. (define_expand "insv"
  3612.   [(set (zero_extract:SI (match_operand:SI 0 "general_operand" "")
  3613.              (match_operand:SI 1 "immediate_operand" "")
  3614.              (match_operand:SI 2 "immediate_operand" ""))
  3615.     (match_operand:QI 3 "general_operand" "ri"))]
  3616.   ""
  3617.   "
  3618. {
  3619.   if (GET_CODE (operands[1]) != CONST_INT
  3620.       || GET_CODE (operands[2]) != CONST_INT)
  3621.     FAIL;
  3622.  
  3623.   if (! (INTVAL (operands[1]) == 8
  3624.      && (INTVAL (operands[2]) == 8 || INTVAL (operands[2]) == 0))
  3625.       && ! INTVAL (operands[1]) == 1)
  3626.     FAIL;
  3627. }")
  3628.  
  3629. ;; ??? Are these constraints right?
  3630. (define_insn ""
  3631.   [(set (zero_extract:SI (match_operand:SI 0 "general_operand" "+&qo")
  3632.              (const_int 8)
  3633.              (const_int 8))
  3634.     (match_operand:QI 1 "general_operand" "qn"))]
  3635.   ""
  3636.   "*
  3637. {
  3638.   if (REG_P (operands[0]))
  3639.     return AS2 (mov%B0,%1,%h0);
  3640.  
  3641.   operands[0] = adj_offsettable_operand (operands[0], 1);
  3642.   return AS2 (mov%B0,%1,%0);
  3643. }")
  3644. */
  3645.  
  3646. ;; On i386, the register count for a bit operation is *not* truncated,
  3647. ;; so SHIFT_COUNT_TRUNCATED must not be defined.
  3648.  
  3649. ;; On i486, the shift & or/and code is faster than bts or btr.  If
  3650. ;; operands[0] is a MEM, the bt[sr] is half as fast as the normal code.
  3651.  
  3652. ;; On i386, bts is a little faster if operands[0] is a reg, and a
  3653. ;; little slower if operands[0] is a MEM, than the shift & or/and code.
  3654. ;; Use bts & btr, since they reload better.
  3655.  
  3656. ;; General bit set and clear.
  3657. (define_insn ""
  3658.   [(set (zero_extract:SI (match_operand:SI 0 "general_operand" "+rm")
  3659.              (const_int 1)
  3660.              (match_operand:SI 2 "general_operand" "r"))
  3661.     (match_operand:SI 3 "const_int_operand" "n"))]
  3662.   "! TARGET_486 && GET_CODE (operands[2]) != CONST_INT"
  3663.   "*
  3664. {
  3665.   CC_STATUS_INIT;
  3666.  
  3667.   if (INTVAL (operands[3]) == 1)
  3668.     return AS2 (bts%L0,%2,%0);
  3669.   else
  3670.     return AS2 (btr%L0,%2,%0);
  3671. }")
  3672.  
  3673. ;; Bit complement.  See comments on previous pattern.
  3674. ;; ??? Is this really worthwhile?
  3675. (define_insn ""
  3676.   [(set (match_operand:SI 0 "general_operand" "=rm")
  3677.     (xor:SI (ashift:SI (const_int 1)
  3678.                (match_operand:SI 1 "general_operand" "r"))
  3679.         (match_operand:SI 2 "general_operand" "0")))]
  3680.   "! TARGET_486 && GET_CODE (operands[1]) != CONST_INT"
  3681.   "*
  3682. {
  3683.   CC_STATUS_INIT;
  3684.  
  3685.   return AS2 (btc%L0,%1,%0);
  3686. }")
  3687.  
  3688. (define_insn ""
  3689.   [(set (match_operand:SI 0 "general_operand" "=rm")
  3690.     (xor:SI (match_operand:SI 1 "general_operand" "0")
  3691.         (ashift:SI (const_int 1)
  3692.                (match_operand:SI 2 "general_operand" "r"))))]
  3693.   "! TARGET_486 && GET_CODE (operands[2]) != CONST_INT"
  3694.   "*
  3695. {
  3696.   CC_STATUS_INIT;
  3697.  
  3698.   return AS2 (btc%L0,%2,%0);
  3699. }")
  3700.  
  3701. ;; Recognizers for bit-test instructions.
  3702.  
  3703. ;; The bt opcode allows a MEM in operands[0].  But on both i386 and
  3704. ;; i486, it is faster to copy a MEM to REG and then use bt, than to use
  3705. ;; bt on the MEM directly.
  3706.  
  3707. ;; ??? The first argument of a zero_extract must not be reloaded, so
  3708. ;; don't allow a MEM in the operand predicate without allowing it in the
  3709. ;; constraint.
  3710.  
  3711. (define_insn ""
  3712.   [(set (cc0) (zero_extract (match_operand:SI 0 "register_operand" "r")
  3713.                 (const_int 1)
  3714.                 (match_operand:SI 1 "general_operand" "r")))]
  3715.   "GET_CODE (operands[1]) != CONST_INT"
  3716.   "*
  3717. {
  3718.   cc_status.flags |= CC_Z_IN_NOT_C;
  3719.   return AS2 (bt%L0,%1,%0);
  3720. }")
  3721.  
  3722. (define_insn ""
  3723.   [(set (cc0) (zero_extract (match_operand:SI 0 "register_operand" "r")
  3724.                 (match_operand:SI 1 "const_int_operand" "n")
  3725.                 (match_operand:SI 2 "const_int_operand" "n")))]
  3726.   ""
  3727.   "*
  3728. {
  3729.   unsigned int mask;
  3730.  
  3731.   mask = ((1 << INTVAL (operands[1])) - 1) << INTVAL (operands[2]);
  3732.   operands[1] = GEN_INT (mask);
  3733.  
  3734.   if (QI_REG_P (operands[0]))
  3735.     {
  3736.       if ((mask & ~0xff) == 0)
  3737.         {
  3738.       cc_status.flags |= CC_NOT_NEGATIVE;
  3739.       return AS2 (test%B0,%1,%b0);
  3740.     }
  3741.  
  3742.       if ((mask & ~0xff00) == 0)
  3743.         {
  3744.       cc_status.flags |= CC_NOT_NEGATIVE;
  3745.       operands[1] = GEN_INT (mask >> 8);
  3746.       return AS2 (test%B0,%1,%h0);
  3747.     }
  3748.     }
  3749.  
  3750.   return AS2 (test%L0,%1,%0);
  3751. }")
  3752.  
  3753. ;; ??? All bets are off if operand 0 is a volatile MEM reference.
  3754. ;; The CPU may access unspecified bytes around the actual target byte.
  3755.  
  3756. (define_insn ""
  3757.   [(set (cc0) (zero_extract (match_operand:QI 0 "general_operand" "rm")
  3758.                 (match_operand:SI 1 "const_int_operand" "n")
  3759.                 (match_operand:SI 2 "const_int_operand" "n")))]
  3760.   "GET_CODE (operands[0]) != MEM || ! MEM_VOLATILE_P (operands[0])"
  3761.   "*
  3762. {
  3763.   unsigned int mask;
  3764.  
  3765.   mask = ((1 << INTVAL (operands[1])) - 1) << INTVAL (operands[2]);
  3766.   operands[1] = GEN_INT (mask);
  3767.  
  3768.   if (! REG_P (operands[0]) || QI_REG_P (operands[0]))
  3769.     {
  3770.       if ((mask & ~0xff) == 0)
  3771.         {
  3772.       cc_status.flags |= CC_NOT_NEGATIVE;
  3773.       return AS2 (test%B0,%1,%b0);
  3774.     }
  3775.  
  3776.       if ((mask & ~0xff00) == 0)
  3777.         {
  3778.       cc_status.flags |= CC_NOT_NEGATIVE;
  3779.       operands[1] = GEN_INT (mask >> 8);
  3780.  
  3781.       if (QI_REG_P (operands[0]))
  3782.         return AS2 (test%B0,%1,%h0);
  3783.       else
  3784.         {
  3785.           operands[0] = adj_offsettable_operand (operands[0], 1);
  3786.           return AS2 (test%B0,%1,%b0);
  3787.         }
  3788.     }
  3789.  
  3790.       if (GET_CODE (operands[0]) == MEM && (mask & ~0xff0000) == 0)
  3791.         {
  3792.       cc_status.flags |= CC_NOT_NEGATIVE;
  3793.       operands[1] = GEN_INT (mask >> 16);
  3794.       operands[0] = adj_offsettable_operand (operands[0], 2);
  3795.       return AS2 (test%B0,%1,%b0);
  3796.     }
  3797.  
  3798.       if (GET_CODE (operands[0]) == MEM && (mask & ~0xff000000) == 0)
  3799.         {
  3800.       cc_status.flags |= CC_NOT_NEGATIVE;
  3801.       operands[1] = GEN_INT (mask >> 24);
  3802.       operands[0] = adj_offsettable_operand (operands[0], 3);
  3803.       return AS2 (test%B0,%1,%b0);
  3804.     }
  3805.     }
  3806.  
  3807.   if (CONSTANT_P (operands[1]) || GET_CODE (operands[0]) == MEM)
  3808.     return AS2 (test%L0,%1,%0);
  3809.  
  3810.   return AS2 (test%L1,%0,%1);
  3811. }")
  3812.  
  3813. ;; Store-flag instructions.
  3814.  
  3815. ;; For all sCOND expanders, also expand the compare or test insn that
  3816. ;; generates cc0.  Generate an equality comparison if `seq' or `sne'.
  3817.  
  3818. ;; The 386 sCOND opcodes can write to memory.  But a gcc sCOND insn may
  3819. ;; not have any input reloads.  A MEM write might need an input reload
  3820. ;; for the address of the MEM.  So don't allow MEM as the SET_DEST.
  3821.  
  3822. (define_expand "seq"
  3823.   [(match_dup 1)
  3824.    (set (match_operand:QI 0 "register_operand" "")
  3825.     (eq:QI (cc0) (const_int 0)))]
  3826.   ""
  3827.   "
  3828. {
  3829.   if (TARGET_IEEE_FP
  3830.       && GET_MODE_CLASS (GET_MODE (i386_compare_op0)) == MODE_FLOAT)
  3831.     operands[1] = (*i386_compare_gen_eq)(i386_compare_op0, i386_compare_op1);
  3832.   else
  3833.     operands[1] = (*i386_compare_gen)(i386_compare_op0, i386_compare_op1);
  3834. }")
  3835.  
  3836. (define_insn ""
  3837.   [(set (match_operand:QI 0 "register_operand" "=q")
  3838.     (eq:QI (cc0) (const_int 0)))]
  3839.   ""
  3840.   "*
  3841. {
  3842.   if (cc_prev_status.flags & CC_Z_IN_NOT_C)
  3843.     return AS1 (setnb,%0);
  3844.   else
  3845.     return AS1 (sete,%0);
  3846. }")
  3847.  
  3848. (define_expand "sne"
  3849.   [(match_dup 1)
  3850.    (set (match_operand:QI 0 "register_operand" "")
  3851.     (ne:QI (cc0) (const_int 0)))]
  3852.   ""
  3853.   "
  3854. {
  3855.   if (TARGET_IEEE_FP
  3856.       && GET_MODE_CLASS (GET_MODE (i386_compare_op0)) == MODE_FLOAT)
  3857.     operands[1] = (*i386_compare_gen_eq)(i386_compare_op0, i386_compare_op1);
  3858.   else
  3859.     operands[1] = (*i386_compare_gen)(i386_compare_op0, i386_compare_op1);
  3860. }")
  3861.  
  3862. (define_insn ""
  3863.   [(set (match_operand:QI 0 "register_operand" "=q")
  3864.     (ne:QI (cc0) (const_int 0)))]
  3865.   ""
  3866.   "*
  3867. {
  3868.   if (cc_prev_status.flags & CC_Z_IN_NOT_C)
  3869.     return AS1 (setb,%0);
  3870.   else
  3871.     return AS1 (setne,%0);
  3872. }
  3873. ")
  3874.  
  3875. (define_expand "sgt"
  3876.   [(match_dup 1)
  3877.    (set (match_operand:QI 0 "register_operand" "")
  3878.     (gt:QI (cc0) (const_int 0)))]
  3879.   ""
  3880.   "operands[1] = (*i386_compare_gen)(i386_compare_op0, i386_compare_op1);")
  3881.  
  3882. (define_insn ""
  3883.   [(set (match_operand:QI 0 "register_operand" "=q")
  3884.     (gt:QI (cc0) (const_int 0)))]
  3885.   ""
  3886.   "*
  3887. {
  3888.   if (TARGET_IEEE_FP && (cc_prev_status.flags & CC_IN_80387))
  3889.     return AS1 (sete,%0);
  3890.  
  3891.   OUTPUT_JUMP (\"setg %0\", \"seta %0\", NULL_PTR);
  3892. }")
  3893.  
  3894. (define_expand "sgtu"
  3895.   [(match_dup 1)
  3896.    (set (match_operand:QI 0 "register_operand" "")
  3897.     (gtu:QI (cc0) (const_int 0)))]
  3898.   ""
  3899.   "operands[1] = (*i386_compare_gen)(i386_compare_op0, i386_compare_op1);")
  3900.  
  3901. (define_insn ""
  3902.   [(set (match_operand:QI 0 "register_operand" "=q")
  3903.     (gtu:QI (cc0) (const_int 0)))]
  3904.   ""
  3905.   "* return \"seta %0\"; ")
  3906.  
  3907. (define_expand "slt"
  3908.   [(match_dup 1)
  3909.    (set (match_operand:QI 0 "register_operand" "")
  3910.     (lt:QI (cc0) (const_int 0)))]
  3911.   ""
  3912.   "operands[1] = (*i386_compare_gen)(i386_compare_op0, i386_compare_op1);")
  3913.  
  3914. (define_insn ""
  3915.   [(set (match_operand:QI 0 "register_operand" "=q")
  3916.     (lt:QI (cc0) (const_int 0)))]
  3917.   ""
  3918.   "*
  3919. {
  3920.   if (TARGET_IEEE_FP && (cc_prev_status.flags & CC_IN_80387))
  3921.     return AS1 (sete,%0);
  3922.  
  3923.   OUTPUT_JUMP (\"setl %0\", \"setb %0\", \"sets %0\");
  3924. }")
  3925.  
  3926. (define_expand "sltu"
  3927.   [(match_dup 1)
  3928.    (set (match_operand:QI 0 "register_operand" "")
  3929.     (ltu:QI (cc0) (const_int 0)))]
  3930.   ""
  3931.   "operands[1] = (*i386_compare_gen)(i386_compare_op0, i386_compare_op1);")
  3932.  
  3933. (define_insn ""
  3934.   [(set (match_operand:QI 0 "register_operand" "=q")
  3935.     (ltu:QI (cc0) (const_int 0)))]
  3936.   ""
  3937.   "* return \"setb %0\"; ")
  3938.  
  3939. (define_expand "sge"
  3940.   [(match_dup 1)
  3941.    (set (match_operand:QI 0 "register_operand" "")
  3942.     (ge:QI (cc0) (const_int 0)))]
  3943.   ""
  3944.   "operands[1] = (*i386_compare_gen)(i386_compare_op0, i386_compare_op1);")
  3945.  
  3946. (define_insn ""
  3947.   [(set (match_operand:QI 0 "register_operand" "=q")
  3948.     (ge:QI (cc0) (const_int 0)))]
  3949.   ""
  3950.   "*
  3951. {
  3952.   if (TARGET_IEEE_FP && (cc_prev_status.flags & CC_IN_80387))
  3953.     return AS1 (sete,%0);
  3954.  
  3955.   OUTPUT_JUMP (\"setge %0\", \"setae %0\", \"setns %0\");
  3956. }")
  3957.  
  3958. (define_expand "sgeu"
  3959.   [(match_dup 1)
  3960.    (set (match_operand:QI 0 "register_operand" "")
  3961.     (geu:QI (cc0) (const_int 0)))]
  3962.   ""
  3963.   "operands[1] = (*i386_compare_gen)(i386_compare_op0, i386_compare_op1);")
  3964.  
  3965. (define_insn ""
  3966.   [(set (match_operand:QI 0 "register_operand" "=q")
  3967.     (geu:QI (cc0) (const_int 0)))]
  3968.   ""
  3969.   "* return \"setae %0\"; ")
  3970.  
  3971. (define_expand "sle"
  3972.   [(match_dup 1)
  3973.    (set (match_operand:QI 0 "register_operand" "")
  3974.     (le:QI (cc0) (const_int 0)))]
  3975.   ""
  3976.   "operands[1] = (*i386_compare_gen)(i386_compare_op0, i386_compare_op1);")
  3977.  
  3978. (define_insn ""
  3979.   [(set (match_operand:QI 0 "register_operand" "=q")
  3980.     (le:QI (cc0) (const_int 0)))]
  3981.   ""
  3982.   "*
  3983. {
  3984.   if (TARGET_IEEE_FP && (cc_prev_status.flags & CC_IN_80387))
  3985.     return AS1 (setb,%0);
  3986.  
  3987.   OUTPUT_JUMP (\"setle %0\", \"setbe %0\", NULL_PTR);
  3988. }")
  3989.  
  3990. (define_expand "sleu"
  3991.   [(match_dup 1)
  3992.    (set (match_operand:QI 0 "register_operand" "")
  3993.     (leu:QI (cc0) (const_int 0)))]
  3994.   ""
  3995.   "operands[1] = (*i386_compare_gen)(i386_compare_op0, i386_compare_op1);")
  3996.  
  3997. (define_insn ""
  3998.   [(set (match_operand:QI 0 "register_operand" "=q")
  3999.     (leu:QI (cc0) (const_int 0)))]
  4000.   ""
  4001.   "* return \"setbe %0\"; ")
  4002.  
  4003. ;; Basic conditional jump instructions.
  4004. ;; We ignore the overflow flag for signed branch instructions.
  4005.  
  4006. ;; For all bCOND expanders, also expand the compare or test insn that
  4007. ;; generates cc0.  Generate an equality comparison if `beq' or `bne'.
  4008.  
  4009. (define_expand "beq"
  4010.   [(match_dup 1)
  4011.    (set (pc)
  4012.     (if_then_else (eq (cc0)
  4013.               (const_int 0))
  4014.               (label_ref (match_operand 0 "" ""))
  4015.               (pc)))]
  4016.   ""
  4017.   "
  4018. {
  4019.   if (TARGET_IEEE_FP
  4020.       && GET_MODE_CLASS (GET_MODE (i386_compare_op0)) == MODE_FLOAT)
  4021.     operands[1] = (*i386_compare_gen_eq)(i386_compare_op0, i386_compare_op1);
  4022.   else
  4023.     operands[1] = (*i386_compare_gen)(i386_compare_op0, i386_compare_op1);
  4024. }")
  4025.  
  4026. (define_insn ""
  4027.   [(set (pc)
  4028.     (if_then_else (eq (cc0)
  4029.               (const_int 0))
  4030.               (label_ref (match_operand 0 "" ""))
  4031.               (pc)))]
  4032.   ""
  4033.   "*
  4034. {
  4035.   if (cc_prev_status.flags & CC_Z_IN_NOT_C)
  4036.     return \"jnc %l0\";
  4037.   else
  4038.     return \"je %l0\";
  4039. }")
  4040.  
  4041. (define_expand "bne"
  4042.   [(match_dup 1)
  4043.    (set (pc)
  4044.     (if_then_else (ne (cc0)
  4045.               (const_int 0))
  4046.               (label_ref (match_operand 0 "" ""))
  4047.               (pc)))]
  4048.   ""
  4049.   "
  4050. {
  4051.   if (TARGET_IEEE_FP
  4052.       && GET_MODE_CLASS (GET_MODE (i386_compare_op0)) == MODE_FLOAT)
  4053.     operands[1] = (*i386_compare_gen_eq)(i386_compare_op0, i386_compare_op1);
  4054.   else
  4055.     operands[1] = (*i386_compare_gen)(i386_compare_op0, i386_compare_op1);
  4056. }")
  4057.  
  4058. (define_insn ""
  4059.   [(set (pc)
  4060.     (if_then_else (ne (cc0)
  4061.               (const_int 0))
  4062.               (label_ref (match_operand 0 "" ""))
  4063.               (pc)))]
  4064.   ""
  4065.   "*
  4066. {
  4067.   if (cc_prev_status.flags & CC_Z_IN_NOT_C)
  4068.     return \"jc %l0\";
  4069.   else
  4070.     return \"jne %l0\";
  4071. }")
  4072.  
  4073. (define_expand "bgt"
  4074.   [(match_dup 1)
  4075.    (set (pc)
  4076.     (if_then_else (gt (cc0)
  4077.               (const_int 0))
  4078.               (label_ref (match_operand 0 "" ""))
  4079.               (pc)))]
  4080.   ""
  4081.   "operands[1] = (*i386_compare_gen)(i386_compare_op0, i386_compare_op1);")
  4082.  
  4083. (define_insn ""
  4084.   [(set (pc)
  4085.     (if_then_else (gt (cc0)
  4086.               (const_int 0))
  4087.               (label_ref (match_operand 0 "" ""))
  4088.               (pc)))]
  4089.   ""
  4090.   "*
  4091. {
  4092.   if (TARGET_IEEE_FP && (cc_prev_status.flags & CC_IN_80387))
  4093.     return AS1 (je,%l0);
  4094.  
  4095.   OUTPUT_JUMP (\"jg %l0\", \"ja %l0\", NULL_PTR);
  4096. }")
  4097.  
  4098. (define_expand "bgtu"
  4099.   [(match_dup 1)
  4100.    (set (pc)
  4101.     (if_then_else (gtu (cc0)
  4102.                (const_int 0))
  4103.               (label_ref (match_operand 0 "" ""))
  4104.               (pc)))]
  4105.   ""
  4106.   "operands[1] = (*i386_compare_gen)(i386_compare_op0, i386_compare_op1);")
  4107.  
  4108. (define_insn ""
  4109.   [(set (pc)
  4110.     (if_then_else (gtu (cc0)
  4111.                (const_int 0))
  4112.               (label_ref (match_operand 0 "" ""))
  4113.               (pc)))]
  4114.   ""
  4115.   "ja %l0")
  4116.  
  4117. (define_expand "blt"
  4118.   [(match_dup 1)
  4119.    (set (pc)
  4120.     (if_then_else (lt (cc0)
  4121.               (const_int 0))
  4122.               (label_ref (match_operand 0 "" ""))
  4123.               (pc)))]
  4124.   ""
  4125.   "operands[1] = (*i386_compare_gen)(i386_compare_op0, i386_compare_op1);")
  4126.  
  4127. (define_insn ""
  4128.   [(set (pc)
  4129.     (if_then_else (lt (cc0)
  4130.               (const_int 0))
  4131.               (label_ref (match_operand 0 "" ""))
  4132.               (pc)))]
  4133.   ""
  4134.   "*
  4135. {
  4136.   if (TARGET_IEEE_FP && (cc_prev_status.flags & CC_IN_80387))
  4137.     return AS1 (je,%l0);
  4138.  
  4139.   OUTPUT_JUMP (\"jl %l0\", \"jb %l0\", \"js %l0\");
  4140. }")
  4141.  
  4142. (define_expand "bltu"
  4143.   [(match_dup 1)
  4144.    (set (pc)
  4145.     (if_then_else (ltu (cc0)
  4146.                (const_int 0))
  4147.               (label_ref (match_operand 0 "" ""))
  4148.               (pc)))]
  4149.   ""
  4150.   "operands[1] = (*i386_compare_gen)(i386_compare_op0, i386_compare_op1);")
  4151.  
  4152. (define_insn ""
  4153.   [(set (pc)
  4154.     (if_then_else (ltu (cc0)
  4155.                (const_int 0))
  4156.               (label_ref (match_operand 0 "" ""))
  4157.               (pc)))]
  4158.   ""
  4159.   "jb %l0")
  4160.  
  4161. (define_expand "bge"
  4162.   [(match_dup 1)
  4163.    (set (pc)
  4164.     (if_then_else (ge (cc0)
  4165.               (const_int 0))
  4166.               (label_ref (match_operand 0 "" ""))
  4167.               (pc)))]
  4168.   ""
  4169.   "operands[1] = (*i386_compare_gen)(i386_compare_op0, i386_compare_op1);")
  4170.  
  4171. (define_insn ""
  4172.   [(set (pc)
  4173.     (if_then_else (ge (cc0)
  4174.               (const_int 0))
  4175.               (label_ref (match_operand 0 "" ""))
  4176.               (pc)))]
  4177.   ""
  4178.   "*
  4179. {
  4180.   if (TARGET_IEEE_FP && (cc_prev_status.flags & CC_IN_80387))
  4181.     return AS1 (je,%l0);
  4182.  
  4183.   OUTPUT_JUMP (\"jge %l0\", \"jae %l0\", \"jns %l0\");
  4184. }")
  4185.  
  4186. (define_expand "bgeu"
  4187.   [(match_dup 1)
  4188.    (set (pc)
  4189.     (if_then_else (geu (cc0)
  4190.                (const_int 0))
  4191.               (label_ref (match_operand 0 "" ""))
  4192.               (pc)))]
  4193.   ""
  4194.   "operands[1] = (*i386_compare_gen)(i386_compare_op0, i386_compare_op1);")
  4195.  
  4196. (define_insn ""
  4197.   [(set (pc)
  4198.     (if_then_else (geu (cc0)
  4199.                (const_int 0))
  4200.               (label_ref (match_operand 0 "" ""))
  4201.               (pc)))]
  4202.   ""
  4203.   "jae %l0")
  4204.  
  4205. (define_expand "ble"
  4206.   [(match_dup 1)
  4207.    (set (pc)
  4208.     (if_then_else (le (cc0)
  4209.               (const_int 0))
  4210.               (label_ref (match_operand 0 "" ""))
  4211.               (pc)))]
  4212.   ""
  4213.   "operands[1] = (*i386_compare_gen)(i386_compare_op0, i386_compare_op1);")
  4214.  
  4215. (define_insn ""
  4216.   [(set (pc)
  4217.     (if_then_else (le (cc0)
  4218.               (const_int 0))
  4219.               (label_ref (match_operand 0 "" ""))
  4220.               (pc)))]
  4221.   ""
  4222.   "*
  4223. {
  4224.   if (TARGET_IEEE_FP && (cc_prev_status.flags & CC_IN_80387))
  4225.     return AS1 (jb,%l0);
  4226.  
  4227.   OUTPUT_JUMP (\"jle %l0\", \"jbe %l0\", NULL_PTR);
  4228. }")
  4229.  
  4230. (define_expand "bleu"
  4231.   [(match_dup 1)
  4232.    (set (pc)
  4233.     (if_then_else (leu (cc0)
  4234.                (const_int 0))
  4235.               (label_ref (match_operand 0 "" ""))
  4236.               (pc)))]
  4237.   ""
  4238.   "operands[1] = (*i386_compare_gen)(i386_compare_op0, i386_compare_op1);")
  4239.  
  4240. (define_insn ""
  4241.   [(set (pc)
  4242.     (if_then_else (leu (cc0)
  4243.                (const_int 0))
  4244.               (label_ref (match_operand 0 "" ""))
  4245.               (pc)))]
  4246.   ""
  4247.   "jbe %l0")
  4248.  
  4249. ;; Negated conditional jump instructions.
  4250.  
  4251. (define_insn ""
  4252.   [(set (pc)
  4253.     (if_then_else (eq (cc0)
  4254.               (const_int 0))
  4255.               (pc)
  4256.               (label_ref (match_operand 0 "" ""))))]
  4257.   ""
  4258.   "*
  4259. {
  4260.   if (cc_prev_status.flags & CC_Z_IN_NOT_C)
  4261.     return \"jc %l0\";
  4262.   else
  4263.     return \"jne %l0\";
  4264. }")
  4265.  
  4266. (define_insn ""
  4267.   [(set (pc)
  4268.     (if_then_else (ne (cc0)
  4269.               (const_int 0))
  4270.               (pc)
  4271.               (label_ref (match_operand 0 "" ""))))]
  4272.   ""
  4273.   "*
  4274. {
  4275.   if (cc_prev_status.flags & CC_Z_IN_NOT_C)
  4276.     return \"jnc %l0\";
  4277.   else
  4278.     return \"je %l0\";
  4279. }")
  4280.  
  4281. (define_insn ""
  4282.   [(set (pc)
  4283.     (if_then_else (gt (cc0)
  4284.               (const_int 0))
  4285.               (pc)
  4286.               (label_ref (match_operand 0 "" ""))))]
  4287.   ""
  4288.   "*
  4289. {
  4290.   if (TARGET_IEEE_FP && (cc_prev_status.flags & CC_IN_80387))
  4291.     return AS1 (jne,%l0);
  4292.  
  4293.   OUTPUT_JUMP (\"jle %l0\", \"jbe %l0\", NULL_PTR);
  4294. }")
  4295.  
  4296. (define_insn ""
  4297.   [(set (pc)
  4298.     (if_then_else (gtu (cc0)
  4299.                (const_int 0))
  4300.               (pc)
  4301.               (label_ref (match_operand 0 "" ""))))]
  4302.   ""
  4303.   "jbe %l0")
  4304.  
  4305. (define_insn ""
  4306.   [(set (pc)
  4307.     (if_then_else (lt (cc0)
  4308.               (const_int 0))
  4309.               (pc)
  4310.               (label_ref (match_operand 0 "" ""))))]
  4311.   ""
  4312.   "*
  4313. {
  4314.   if (TARGET_IEEE_FP && (cc_prev_status.flags & CC_IN_80387))
  4315.     return AS1 (jne,%l0);
  4316.  
  4317.   OUTPUT_JUMP (\"jge %l0\", \"jae %l0\", \"jns %l0\");
  4318. }")
  4319.  
  4320. (define_insn ""
  4321.   [(set (pc)
  4322.     (if_then_else (ltu (cc0)
  4323.                (const_int 0))
  4324.               (pc)
  4325.               (label_ref (match_operand 0 "" ""))))]
  4326.   ""
  4327.   "jae %l0")
  4328.  
  4329. (define_insn ""
  4330.   [(set (pc)
  4331.     (if_then_else (ge (cc0)
  4332.               (const_int 0))
  4333.               (pc)
  4334.               (label_ref (match_operand 0 "" ""))))]
  4335.   ""
  4336.   "*
  4337. {
  4338.   if (TARGET_IEEE_FP && (cc_prev_status.flags & CC_IN_80387))
  4339.     return AS1 (jne,%l0);
  4340.  
  4341.   OUTPUT_JUMP (\"jl %l0\", \"jb %l0\", \"js %l0\");
  4342. }")
  4343.  
  4344. (define_insn ""
  4345.   [(set (pc)
  4346.     (if_then_else (geu (cc0)
  4347.                (const_int 0))
  4348.               (pc)
  4349.               (label_ref (match_operand 0 "" ""))))]
  4350.   ""
  4351.   "jb %l0")
  4352.  
  4353. (define_insn ""
  4354.   [(set (pc)
  4355.     (if_then_else (le (cc0)
  4356.               (const_int 0))
  4357.               (pc)
  4358.               (label_ref (match_operand 0 "" ""))))]
  4359.   ""
  4360.   "*
  4361. {
  4362.   if (TARGET_IEEE_FP && (cc_prev_status.flags & CC_IN_80387))
  4363.     return AS1 (jae,%l0);
  4364.  
  4365.   OUTPUT_JUMP (\"jg %l0\", \"ja %l0\", NULL_PTR);
  4366. }")
  4367.  
  4368. (define_insn ""
  4369.   [(set (pc)
  4370.     (if_then_else (leu (cc0)
  4371.                (const_int 0))
  4372.               (pc)
  4373.               (label_ref (match_operand 0 "" ""))))]
  4374.   ""
  4375.   "ja %l0")
  4376.  
  4377. ;; Unconditional and other jump instructions
  4378.  
  4379. (define_insn "jump"
  4380.   [(set (pc)
  4381.     (label_ref (match_operand 0 "" "")))]
  4382.   ""
  4383.   "jmp %l0")
  4384.  
  4385. (define_insn "indirect_jump"
  4386.   [(set (pc) (match_operand:SI 0 "general_operand" "rm"))]
  4387.   ""
  4388.   "*
  4389. {
  4390.   CC_STATUS_INIT;
  4391.  
  4392.   return AS1 (jmp,%*%0);
  4393. }")
  4394.  
  4395. ;; Implement switch statements when generating PIC code.  Switches are
  4396. ;; implemented by `tablejump' when not using -fpic.
  4397.  
  4398. ;; Emit code here to do the range checking and make the index zero based.
  4399.  
  4400. (define_expand "casesi"
  4401.   [(set (match_dup 5)
  4402.     (minus:SI (match_operand:SI 0 "general_operand" "")
  4403.           (match_operand:SI 1 "general_operand" "")))
  4404.    (set (cc0)
  4405.     (compare:CC (match_dup 5)
  4406.             (match_operand:SI 2 "general_operand" "")))
  4407.    (set (pc)
  4408.     (if_then_else (gtu (cc0)
  4409.                (const_int 0))
  4410.               (label_ref (match_operand 4 "" ""))
  4411.               (pc)))
  4412.    (parallel
  4413.     [(set (pc)
  4414.       (minus:SI (reg:SI 3)
  4415.             (mem:SI (plus:SI (mult:SI (match_dup 5)
  4416.                           (const_int 4))
  4417.                      (label_ref (match_operand 3 "" ""))))))
  4418.      (clobber (match_scratch:SI 6 ""))])]
  4419.   "flag_pic"
  4420.   "
  4421. {
  4422.   operands[5] = gen_reg_rtx (SImode);
  4423.   current_function_uses_pic_offset_table = 1;
  4424. }")
  4425.  
  4426. ;; Implement a casesi insn.
  4427.  
  4428. ;; Each entry in the "addr_diff_vec" looks like this as the result of the
  4429. ;; two rules below:
  4430. ;; 
  4431. ;;     .long _GLOBAL_OFFSET_TABLE_+[.-.L2]
  4432. ;; 
  4433. ;; 1. An expression involving an external reference may only use the
  4434. ;;    addition operator, and only with an assembly-time constant.
  4435. ;;    The example above satisfies this because ".-.L2" is a constant.
  4436. ;; 
  4437. ;; 2. The symbol _GLOBAL_OFFSET_TABLE_ is magic, and at link time is
  4438. ;;    given the value of "GOT - .", where GOT is the actual address of
  4439. ;;    the Global Offset Table.  Therefore, the .long above actually
  4440. ;;    stores the value "( GOT - . ) + [ . - .L2 ]", or "GOT - .L2".  The
  4441. ;;    expression "GOT - .L2" by itself would generate an error from as(1).
  4442. ;; 
  4443. ;; The pattern below emits code that looks like this:
  4444. ;; 
  4445. ;;     movl %ebx,reg
  4446. ;;     subl TABLE@GOTOFF(%ebx,index,4),reg
  4447. ;;     jmp reg
  4448. ;; 
  4449. ;; The addr_diff_vec contents may be directly referenced with @GOTOFF, since
  4450. ;; the addr_diff_vec is known to be part of this module.
  4451. ;; 
  4452. ;; The subl above calculates "GOT - (( GOT - . ) + [ . - .L2 ])", which
  4453. ;; evaluates to just ".L2".
  4454.  
  4455. (define_insn ""
  4456.   [(set (pc)
  4457.     (minus:SI (reg:SI 3)
  4458.           (mem:SI (plus:SI
  4459.                (mult:SI (match_operand:SI 0 "register_operand" "r")
  4460.                     (const_int 4))
  4461.                (label_ref (match_operand 1 "" ""))))))
  4462.    (clobber (match_scratch:SI 2 "=&r"))]
  4463.   ""
  4464.   "*
  4465. {
  4466.   rtx xops[4];
  4467.  
  4468.   xops[0] = operands[0];
  4469.   xops[1] = operands[1];
  4470.   xops[2] = operands[2];
  4471.   xops[3] = pic_offset_table_rtx;
  4472.  
  4473.   output_asm_insn (AS2 (mov%L2,%3,%2), xops);
  4474.   output_asm_insn (\"sub%L2 %l1@GOTOFF(%3,%0,4),%2\", xops);
  4475.   output_asm_insn (AS1 (jmp,%*%2), xops);
  4476.   ASM_OUTPUT_ALIGN_CODE (asm_out_file);
  4477.   RET;
  4478. }")
  4479.  
  4480. (define_insn "tablejump"
  4481.   [(set (pc) (match_operand:SI 0 "general_operand" "rm"))
  4482.    (use (label_ref (match_operand 1 "" "")))]
  4483.   ""
  4484.   "*
  4485. {
  4486.   CC_STATUS_INIT;
  4487.  
  4488.   return AS1 (jmp,%*%0);
  4489. }")
  4490.  
  4491. ;; Call insns.
  4492.  
  4493. ;; If generating PIC code, the predicate indirect_operand will fail
  4494. ;; for operands[0] containing symbolic references on all of the named
  4495. ;; call* patterns.  Each named pattern is followed by an unnamed pattern
  4496. ;; that matches any call to a symbolic CONST (ie, a symbol_ref).  The
  4497. ;; unnamed patterns are only used while generating PIC code, because
  4498. ;; otherwise the named patterns match.
  4499.  
  4500. ;; Call subroutine returning no value.
  4501.  
  4502. (define_expand "call_pop"
  4503.   [(parallel [(call (match_operand:QI 0 "indirect_operand" "")
  4504.             (match_operand:SI 1 "general_operand" ""))
  4505.           (set (reg:SI 7)
  4506.            (plus:SI (reg:SI 7)
  4507.                 (match_operand:SI 3 "immediate_operand" "")))])]
  4508.   ""
  4509.   "
  4510. {
  4511.   rtx addr;
  4512.  
  4513.   if (flag_pic)
  4514.     current_function_uses_pic_offset_table = 1;
  4515.  
  4516.   /* With half-pic, force the address into a register.  */
  4517.   addr = XEXP (operands[0], 0);
  4518.   if (GET_CODE (addr) != REG && HALF_PIC_P () && !CONSTANT_ADDRESS_P (addr))
  4519.     XEXP (operands[0], 0) = force_reg (Pmode, addr);
  4520.  
  4521.   if (! expander_call_insn_operand (operands[0], QImode))
  4522.     operands[0]
  4523.       = change_address (operands[0], VOIDmode,
  4524.             copy_to_mode_reg (Pmode, XEXP (operands[0], 0)));
  4525. }")
  4526.  
  4527. (define_insn ""
  4528.   [(call (match_operand:QI 0 "call_insn_operand" "m")
  4529.      (match_operand:SI 1 "general_operand" "g"))
  4530.    (set (reg:SI 7) (plus:SI (reg:SI 7)
  4531.                 (match_operand:SI 3 "immediate_operand" "i")))]
  4532.   ""
  4533.   "*
  4534. {
  4535.   if (GET_CODE (operands[0]) == MEM
  4536.       && ! CONSTANT_ADDRESS_P (XEXP (operands[0], 0)))
  4537.     {
  4538.       operands[0] = XEXP (operands[0], 0);
  4539.       return AS1 (call,%*%0);
  4540.     }
  4541.   else
  4542.     return AS1 (call,%P0);
  4543. }")
  4544.  
  4545. (define_insn ""
  4546.   [(call (mem:QI (match_operand:SI 0 "symbolic_operand" ""))
  4547.      (match_operand:SI 1 "general_operand" "g"))
  4548.    (set (reg:SI 7) (plus:SI (reg:SI 7)
  4549.                 (match_operand:SI 3 "immediate_operand" "i")))]
  4550.   "!HALF_PIC_P ()"
  4551.   "call %P0")
  4552.  
  4553. (define_expand "call"
  4554.   [(call (match_operand:QI 0 "indirect_operand" "")
  4555.      (match_operand:SI 1 "general_operand" ""))]
  4556.   ;; Operand 1 not used on the i386.
  4557.   ""
  4558.   "
  4559. {
  4560.   rtx addr;
  4561.  
  4562.   if (flag_pic)
  4563.     current_function_uses_pic_offset_table = 1;
  4564.  
  4565.   /* With half-pic, force the address into a register.  */
  4566.   addr = XEXP (operands[0], 0);
  4567.   if (GET_CODE (addr) != REG && HALF_PIC_P () && !CONSTANT_ADDRESS_P (addr))
  4568.     XEXP (operands[0], 0) = force_reg (Pmode, addr);
  4569.  
  4570.   if (! expander_call_insn_operand (operands[0], QImode))
  4571.     operands[0]
  4572.       = change_address (operands[0], VOIDmode,
  4573.             copy_to_mode_reg (Pmode, XEXP (operands[0], 0)));
  4574. }")
  4575.  
  4576. (define_insn ""
  4577.   [(call (match_operand:QI 0 "call_insn_operand" "m")
  4578.      (match_operand:SI 1 "general_operand" "g"))]
  4579.   ;; Operand 1 not used on the i386.
  4580.   ""
  4581.   "*
  4582. {
  4583.   if (GET_CODE (operands[0]) == MEM
  4584.       && ! CONSTANT_ADDRESS_P (XEXP (operands[0], 0)))
  4585.     {
  4586.       operands[0] = XEXP (operands[0], 0);
  4587.       return AS1 (call,%*%0);
  4588.     }
  4589.   else
  4590.     return AS1 (call,%P0);
  4591. }")
  4592.  
  4593. (define_insn ""
  4594.   [(call (mem:QI (match_operand:SI 0 "symbolic_operand" ""))
  4595.      (match_operand:SI 1 "general_operand" "g"))]
  4596.   ;; Operand 1 not used on the i386.
  4597.   "!HALF_PIC_P ()"
  4598.   "call %P0")
  4599.  
  4600. ;; Call subroutine, returning value in operand 0
  4601. ;; (which must be a hard register).
  4602.  
  4603. (define_expand "call_value_pop"
  4604.   [(parallel [(set (match_operand 0 "" "")
  4605.            (call (match_operand:QI 1 "indirect_operand" "")
  4606.              (match_operand:SI 2 "general_operand" "")))
  4607.           (set (reg:SI 7)
  4608.            (plus:SI (reg:SI 7)
  4609.                 (match_operand:SI 4 "immediate_operand" "")))])]
  4610.   ""
  4611.   "
  4612. {
  4613.   rtx addr;
  4614.  
  4615.   if (flag_pic)
  4616.     current_function_uses_pic_offset_table = 1;
  4617.  
  4618.   /* With half-pic, force the address into a register.  */
  4619.   addr = XEXP (operands[1], 0);
  4620.   if (GET_CODE (addr) != REG && HALF_PIC_P () && !CONSTANT_ADDRESS_P (addr))
  4621.     XEXP (operands[1], 0) = force_reg (Pmode, addr);
  4622.  
  4623.   if (! expander_call_insn_operand (operands[1], QImode))
  4624.     operands[1]
  4625.       = change_address (operands[1], VOIDmode,
  4626.             copy_to_mode_reg (Pmode, XEXP (operands[1], 0)));
  4627. }")
  4628.  
  4629. (define_insn ""
  4630.   [(set (match_operand 0 "" "=rf")
  4631.     (call (match_operand:QI 1 "call_insn_operand" "m")
  4632.           (match_operand:SI 2 "general_operand" "g")))
  4633.    (set (reg:SI 7) (plus:SI (reg:SI 7)
  4634.                 (match_operand:SI 4 "immediate_operand" "i")))]
  4635.   ""
  4636.   "*
  4637. {
  4638.   if (GET_CODE (operands[1]) == MEM
  4639.       && ! CONSTANT_ADDRESS_P (XEXP (operands[1], 0)))
  4640.     {
  4641.       operands[1] = XEXP (operands[1], 0);
  4642.       output_asm_insn (AS1 (call,%*%1), operands);
  4643.     }
  4644.   else
  4645.     output_asm_insn (AS1 (call,%P1), operands);
  4646.  
  4647.   RET;
  4648. }")
  4649.  
  4650. (define_insn ""
  4651.   [(set (match_operand 0 "" "=rf")
  4652.     (call (mem:QI (match_operand:SI 1 "symbolic_operand" ""))
  4653.           (match_operand:SI 2 "general_operand" "g")))
  4654.    (set (reg:SI 7) (plus:SI (reg:SI 7)
  4655.                 (match_operand:SI 4 "immediate_operand" "i")))]
  4656.   "!HALF_PIC_P ()"
  4657.   "call %P1")
  4658.  
  4659. (define_expand "call_value"
  4660.   [(set (match_operand 0 "" "")
  4661.     (call (match_operand:QI 1 "indirect_operand" "")
  4662.           (match_operand:SI 2 "general_operand" "")))]
  4663.   ;; Operand 2 not used on the i386.
  4664.   ""
  4665.   "
  4666. {
  4667.   rtx addr;
  4668.  
  4669.   if (flag_pic)
  4670.     current_function_uses_pic_offset_table = 1;
  4671.  
  4672.   /* With half-pic, force the address into a register.  */
  4673.   addr = XEXP (operands[1], 0);
  4674.   if (GET_CODE (addr) != REG && HALF_PIC_P () && !CONSTANT_ADDRESS_P (addr))
  4675.     XEXP (operands[1], 0) = force_reg (Pmode, addr);
  4676.  
  4677.   if (! expander_call_insn_operand (operands[1], QImode))
  4678.     operands[1]
  4679.       = change_address (operands[1], VOIDmode,
  4680.             copy_to_mode_reg (Pmode, XEXP (operands[1], 0)));
  4681. }")
  4682.  
  4683. (define_insn ""
  4684.   [(set (match_operand 0 "" "=rf")
  4685.     (call (match_operand:QI 1 "call_insn_operand" "m")
  4686.           (match_operand:SI 2 "general_operand" "g")))]
  4687.   ;; Operand 2 not used on the i386.
  4688.   ""
  4689.   "*
  4690. {
  4691.   if (GET_CODE (operands[1]) == MEM
  4692.       && ! CONSTANT_ADDRESS_P (XEXP (operands[1], 0)))
  4693.     {
  4694.       operands[1] = XEXP (operands[1], 0);
  4695.       output_asm_insn (AS1 (call,%*%1), operands);
  4696.     }
  4697.   else
  4698.     output_asm_insn (AS1 (call,%P1), operands);
  4699.  
  4700.   RET;
  4701. }")
  4702.  
  4703. (define_insn ""
  4704.   [(set (match_operand 0 "" "=rf")
  4705.     (call (mem:QI (match_operand:SI 1 "symbolic_operand" ""))
  4706.           (match_operand:SI 2 "general_operand" "g")))]
  4707.   ;; Operand 2 not used on the i386.
  4708.   "!HALF_PIC_P ()"
  4709.   "call %P1")
  4710.  
  4711. (define_expand "untyped_call"
  4712.   [(parallel [(call (match_operand:QI 0 "indirect_operand" "")
  4713.             (const_int 0))
  4714.           (match_operand:BLK 1 "memory_operand" "")
  4715.           (match_operand 2 "" "")])]
  4716.   ""
  4717.   "
  4718. {
  4719.   rtx addr;
  4720.  
  4721.   if (flag_pic)
  4722.     current_function_uses_pic_offset_table = 1;
  4723.  
  4724.   /* With half-pic, force the address into a register.  */
  4725.   addr = XEXP (operands[0], 0);
  4726.   if (GET_CODE (addr) != REG && HALF_PIC_P () && !CONSTANT_ADDRESS_P (addr))
  4727.     XEXP (operands[0], 0) = force_reg (Pmode, addr);
  4728.  
  4729.   operands[1] = change_address (operands[1], DImode, XEXP (operands[1], 0));
  4730.   if (! expander_call_insn_operand (operands[1], QImode))
  4731.     operands[1]
  4732.       = change_address (operands[1], VOIDmode,
  4733.             copy_to_mode_reg (Pmode, XEXP (operands[1], 0)));
  4734. }")
  4735.  
  4736. (define_insn ""
  4737.   [(call (match_operand:QI 0 "call_insn_operand" "m")
  4738.      (const_int 0))
  4739.    (match_operand:DI 1 "memory_operand" "o")
  4740.    (match_operand 2 "" "")]
  4741.   ""
  4742.   "*
  4743. {
  4744.   rtx addr = operands[1];
  4745.  
  4746.   if (GET_CODE (operands[0]) == MEM
  4747.       && ! CONSTANT_ADDRESS_P (XEXP (operands[0], 0)))
  4748.     {
  4749.       operands[0] = XEXP (operands[0], 0);
  4750.       output_asm_insn (AS1 (call,%*%0), operands);
  4751.     }
  4752.   else
  4753.     output_asm_insn (AS1 (call,%P0), operands);
  4754.  
  4755.   operands[2] = gen_rtx (REG, SImode, 0);
  4756.   output_asm_insn (AS2 (mov%L2,%2,%1), operands);
  4757.  
  4758.   operands[2] = gen_rtx (REG, SImode, 1);
  4759.   operands[1] = adj_offsettable_operand (addr, 4);
  4760.   output_asm_insn (AS2 (mov%L2,%2,%1), operands);
  4761.  
  4762.   operands[1] = adj_offsettable_operand (addr, 8);
  4763.   return AS1 (fnsave,%1);
  4764. }")
  4765.  
  4766. (define_insn ""
  4767.   [(call (mem:QI (match_operand:SI 0 "symbolic_operand" ""))
  4768.      (const_int 0))
  4769.    (match_operand:DI 1 "memory_operand" "o")
  4770.    (match_operand 2 "" "")]
  4771.   "!HALF_PIC_P ()"
  4772.   "*
  4773. {
  4774.   rtx addr = operands[1];
  4775.  
  4776.   output_asm_insn (AS1 (call,%P0), operands);
  4777.  
  4778.   operands[2] = gen_rtx (REG, SImode, 0);
  4779.   output_asm_insn (AS2 (mov%L2,%2,%1), operands);
  4780.  
  4781.   operands[2] = gen_rtx (REG, SImode, 1);
  4782.   operands[1] = adj_offsettable_operand (addr, 4);
  4783.   output_asm_insn (AS2 (mov%L2,%2,%1), operands);
  4784.  
  4785.   operands[1] = adj_offsettable_operand (addr, 8);
  4786.   return AS1 (fnsave,%1);
  4787. }")
  4788.  
  4789. ;; We use fnsave and frstor to save and restore the floating point result.
  4790. ;; These are expensive instructions and require a large space to save the
  4791. ;; FPU state.  An more complicated alternative is to use fnstenv to store
  4792. ;; the FPU environment and test whether the stack top is valid.  Store the
  4793. ;; result of the test, and if it is valid, pop and save the value.  The
  4794. ;; untyped_return would check the test and optionally push the saved value.
  4795.  
  4796. (define_expand "untyped_return"
  4797.   [(match_operand:BLK 0 "memory_operand" "")
  4798.    (match_operand 1 "" "")]
  4799.   ""
  4800.   "
  4801. {
  4802.   rtx valreg1 = gen_rtx (REG, SImode, 0);
  4803.   rtx valreg2 = gen_rtx (REG, SImode, 1);
  4804.   rtx result = operands[0];
  4805.  
  4806.   /* Restore the FPU state.  */
  4807.   emit_insn (gen_update_return (change_address (result, SImode,
  4808.                         plus_constant (XEXP (result, 0),
  4809.                                    8))));
  4810.  
  4811.   /* Reload the function value registers.  */
  4812.   emit_move_insn (valreg1, change_address (result, SImode, XEXP (result, 0)));
  4813.   emit_move_insn (valreg2,
  4814.           change_address (result, SImode,
  4815.                   plus_constant (XEXP (result, 0), 4)));
  4816.  
  4817.   /* Put USE insns before the return.  */
  4818.   emit_insn (gen_rtx (USE, VOIDmode, valreg1));
  4819.   emit_insn (gen_rtx (USE, VOIDmode, valreg2));
  4820.  
  4821.   /* Construct the return.  */
  4822.   expand_null_return ();
  4823.  
  4824.   DONE;
  4825. }")
  4826.  
  4827. (define_insn "update_return"
  4828.   [(unspec:SI [(match_operand:SI 0 "memory_operand" "m")] 0)]
  4829.   ""
  4830.   "frstor %0")
  4831.  
  4832. ;; Insn emitted into the body of a function to return from a function.
  4833. ;; This is only done if the function's epilogue is known to be simple.
  4834. ;; See comments for simple_386_epilogue in i386.c.
  4835.  
  4836. (define_insn "return"
  4837.   [(return)]
  4838.   "simple_386_epilogue ()"
  4839.   "*
  4840. {
  4841.   function_epilogue (asm_out_file, get_frame_size ());
  4842.   RET;
  4843. }")
  4844.  
  4845. (define_insn "nop"
  4846.   [(const_int 0)]
  4847.   ""
  4848.   "nop")
  4849.  
  4850. (define_expand "movstrsi"
  4851.   [(parallel [(set (match_operand:BLK 0 "memory_operand" "")
  4852.            (match_operand:BLK 1 "memory_operand" ""))
  4853.           (use (match_operand:SI 2 "const_int_operand" ""))
  4854.           (use (match_operand:SI 3 "const_int_operand" ""))
  4855.           (clobber (match_scratch:SI 4 ""))
  4856.           (clobber (match_dup 5))
  4857.           (clobber (match_dup 6))])]
  4858.   ""
  4859.   "
  4860. {
  4861.   rtx addr0, addr1;
  4862.  
  4863.   if (GET_CODE (operands[2]) != CONST_INT)
  4864.     FAIL;
  4865.  
  4866.   addr0 = copy_to_mode_reg (Pmode, XEXP (operands[0], 0));
  4867.   addr1 = copy_to_mode_reg (Pmode, XEXP (operands[1], 0));
  4868.  
  4869.   operands[5] = addr0;
  4870.   operands[6] = addr1;
  4871.  
  4872.   operands[0] = gen_rtx (MEM, BLKmode, addr0);
  4873.   operands[1] = gen_rtx (MEM, BLKmode, addr1);
  4874. }")
  4875.  
  4876. ;; It might seem that operands 0 & 1 could use predicate register_operand.
  4877. ;; But strength reduction might offset the MEM expression.  So we let
  4878. ;; reload put the address into %edi & %esi.
  4879.  
  4880. (define_insn ""
  4881.   [(set (mem:BLK (match_operand:SI 0 "address_operand" "D"))
  4882.     (mem:BLK (match_operand:SI 1 "address_operand" "S")))
  4883.    (use (match_operand:SI 2 "const_int_operand" "n"))
  4884.    (use (match_operand:SI 3 "immediate_operand" "i"))
  4885.    (clobber (match_scratch:SI 4 "=&c"))
  4886.    (clobber (match_dup 0))
  4887.    (clobber (match_dup 1))]
  4888.   ""
  4889.   "*
  4890. {
  4891.   rtx xops[2];
  4892.  
  4893.   output_asm_insn (\"cld\", operands);
  4894.   if (GET_CODE (operands[2]) == CONST_INT)
  4895.     {
  4896.       if (INTVAL (operands[2]) & ~0x03)
  4897.     {
  4898.       xops[0] = GEN_INT ((INTVAL (operands[2]) >> 2) & 0x3fffffff);
  4899.       xops[1] = operands[4];
  4900.  
  4901.       output_asm_insn (AS2 (mov%L1,%0,%1), xops);
  4902. #ifdef INTEL_SYNTAX
  4903.       output_asm_insn (\"rep movsd\", xops);
  4904. #else
  4905.       output_asm_insn (\"rep\;movsl\", xops);
  4906. #endif
  4907.     }
  4908.       if (INTVAL (operands[2]) & 0x02)
  4909.     output_asm_insn (\"movsw\", operands);
  4910.       if (INTVAL (operands[2]) & 0x01)
  4911.     output_asm_insn (\"movsb\", operands);
  4912.     }
  4913.   else
  4914.     abort ();
  4915.   RET;
  4916. }")
  4917.  
  4918. (define_expand "cmpstrsi"
  4919.   [(parallel [(set (match_operand:SI 0 "general_operand" "")
  4920.            (compare:SI (match_operand:BLK 1 "general_operand" "")
  4921.                    (match_operand:BLK 2 "general_operand" "")))
  4922.           (use (match_operand:SI 3 "general_operand" ""))
  4923.           (use (match_operand:SI 4 "immediate_operand" ""))
  4924.           (clobber (match_dup 5))
  4925.           (clobber (match_dup 6))
  4926.           (clobber (match_dup 3))])]
  4927.   ""
  4928.   "
  4929. {
  4930.   rtx addr1, addr2;
  4931.  
  4932.   addr1 = copy_to_mode_reg (Pmode, XEXP (operands[1], 0));
  4933.   addr2 = copy_to_mode_reg (Pmode, XEXP (operands[2], 0));
  4934.   operands[3] = copy_to_mode_reg (SImode, operands[3]);
  4935.  
  4936.   operands[5] = addr1;
  4937.   operands[6] = addr2;
  4938.  
  4939.   operands[1] = gen_rtx (MEM, BLKmode, addr1);
  4940.   operands[2] = gen_rtx (MEM, BLKmode, addr2);
  4941.  
  4942. }")
  4943.  
  4944. ;; memcmp recognizers.  The `cmpsb' opcode does nothing if the count is
  4945. ;; zero.  Emit extra code to make sure that a zero-length compare is EQ.
  4946.  
  4947. ;; It might seem that operands 0 & 1 could use predicate register_operand.
  4948. ;; But strength reduction might offset the MEM expression.  So we let
  4949. ;; reload put the address into %edi & %esi.
  4950.  
  4951. ;; ??? Most comparisons have a constant length, and it's therefore
  4952. ;; possible to know that the length is non-zero, and to avoid the extra
  4953. ;; code to handle zero-length compares.
  4954.  
  4955. (define_insn ""
  4956.   [(set (match_operand:SI 0 "general_operand" "=&r")
  4957.     (compare:SI (mem:BLK (match_operand:SI 1 "address_operand" "S"))
  4958.             (mem:BLK (match_operand:SI 2 "address_operand" "D"))))
  4959.    (use (match_operand:SI 3 "register_operand" "c"))
  4960.    (use (match_operand:SI 4 "immediate_operand" "i"))
  4961.    (clobber (match_dup 1))
  4962.    (clobber (match_dup 2))
  4963.    (clobber (match_dup 3))]
  4964.   ""
  4965.   "*
  4966. {
  4967.   rtx xops[4], label;
  4968.  
  4969.   label = gen_label_rtx ();
  4970.  
  4971.   output_asm_insn (\"cld\", operands);
  4972.   output_asm_insn (AS2 (xor%L0,%0,%0), operands);
  4973.   output_asm_insn (\"repz\;cmps%B2\", operands);
  4974.   output_asm_insn (\"je %l0\", &label);
  4975.  
  4976.   xops[0] = operands[0];
  4977.   xops[1] = gen_rtx (MEM, QImode,
  4978.              gen_rtx (PLUS, SImode, operands[1], constm1_rtx));
  4979.   xops[2] = gen_rtx (MEM, QImode,
  4980.              gen_rtx (PLUS, SImode, operands[2], constm1_rtx));
  4981.   xops[3] = operands[3];
  4982.  
  4983.   output_asm_insn (AS2 (movz%B1%L0,%1,%0), xops);
  4984.   output_asm_insn (AS2 (movz%B2%L3,%2,%3), xops);
  4985.  
  4986.   output_asm_insn (AS2 (sub%L0,%3,%0), xops);
  4987.   ASM_OUTPUT_INTERNAL_LABEL (asm_out_file, \"L\", CODE_LABEL_NUMBER (label));
  4988.   RET;
  4989. }")
  4990.  
  4991. (define_insn ""
  4992.   [(set (cc0)
  4993.     (compare:SI (mem:BLK (match_operand:SI 0 "address_operand" "S"))
  4994.             (mem:BLK (match_operand:SI 1 "address_operand" "D"))))
  4995.    (use (match_operand:SI 2 "register_operand" "c"))
  4996.    (use (match_operand:SI 3 "immediate_operand" "i"))
  4997.    (clobber (match_dup 0))
  4998.    (clobber (match_dup 1))
  4999.    (clobber (match_dup 2))]
  5000.   ""
  5001.   "*
  5002. {
  5003.   rtx xops[2];
  5004.  
  5005.   cc_status.flags |= CC_NOT_SIGNED;
  5006.  
  5007.   xops[0] = gen_rtx (REG, QImode, 0);
  5008.   xops[1] = CONST0_RTX (QImode);
  5009.  
  5010.   output_asm_insn (\"cld\", operands);
  5011.   output_asm_insn (AS2 (test%B0,%1,%0), xops);
  5012.   return \"repz\;cmps%B2\";
  5013. }")
  5014.  
  5015. (define_expand "ffssi2"
  5016.   [(set (match_dup 2)
  5017.     (plus:SI (ffs:SI (match_operand:SI 1 "general_operand" ""))
  5018.          (const_int -1)))
  5019.    (set (match_operand:SI 0 "general_operand" "")
  5020.     (plus:SI (match_dup 2) (const_int 1)))]
  5021.   ""
  5022.   "operands[2] = gen_reg_rtx (SImode);")
  5023.  
  5024. (define_insn ""
  5025.   [(set (match_operand:SI 0 "general_operand" "=&r")
  5026.     (plus:SI (ffs:SI (match_operand:SI 1 "general_operand" "rm"))
  5027.          (const_int -1)))]
  5028.   ""
  5029.   "*
  5030. {
  5031.   rtx xops[3];
  5032.   static int ffssi_label_number;
  5033.   char buffer[30];
  5034.  
  5035.   xops[0] = operands[0];
  5036.   xops[1] = operands[1];
  5037.   xops[2] = constm1_rtx;
  5038.   /* Can there be a way to avoid the jump here?  */
  5039.   output_asm_insn (AS2 (bsf%L0,%1,%0), xops);
  5040. #ifdef LOCAL_LABEL_PREFIX
  5041.   sprintf (buffer, \"jnz %sLFFSSI%d\",
  5042.        LOCAL_LABEL_PREFIX, ffssi_label_number);
  5043. #else
  5044.   sprintf (buffer, \"jnz %sLFFSSI%d\",
  5045.        \"\", ffssi_label_number);
  5046. #endif
  5047.   output_asm_insn (buffer, xops);
  5048.   output_asm_insn (AS2 (mov%L0,%2,%0), xops);
  5049. #ifdef LOCAL_LABEL_PREFIX
  5050.   sprintf (buffer, \"%sLFFSSI%d:\",
  5051.        LOCAL_LABEL_PREFIX, ffssi_label_number);
  5052. #else
  5053.   sprintf (buffer, \"%sLFFSSI%d:\",
  5054.        \"\", ffssi_label_number);
  5055. #endif
  5056.   output_asm_insn (buffer, xops);
  5057.  
  5058.   ffssi_label_number++;
  5059.   return \"\";
  5060. }")
  5061.  
  5062. (define_expand "ffshi2"
  5063.   [(set (match_dup 2)
  5064.     (plus:HI (ffs:HI (match_operand:HI 1 "general_operand" ""))
  5065.          (const_int -1)))
  5066.    (set (match_operand:HI 0 "general_operand" "")
  5067.     (plus:HI (match_dup 2) (const_int 1)))]
  5068.   ""
  5069.   "operands[2] = gen_reg_rtx (HImode);")
  5070.  
  5071. (define_insn ""
  5072.   [(set (match_operand:HI 0 "general_operand" "=&r")
  5073.     (plus:HI (ffs:HI (match_operand:SI 1 "general_operand" "rm"))
  5074.          (const_int -1)))]
  5075.   ""
  5076.   "*
  5077. {
  5078.   rtx xops[3];
  5079.   static int ffshi_label_number;
  5080.   char buffer[30];
  5081.  
  5082.   xops[0] = operands[0];
  5083.   xops[1] = operands[1];
  5084.   xops[2] = constm1_rtx;
  5085.   output_asm_insn (AS2 (bsf%W0,%1,%0), xops);
  5086. #ifdef LOCAL_LABEL_PREFIX
  5087.   sprintf (buffer, \"jnz %sLFFSHI%d\",
  5088.        LOCAL_LABEL_PREFIX, ffshi_label_number);
  5089. #else
  5090.   sprintf (buffer, \"jnz %sLFFSHI%d\",
  5091.        \"\", ffshi_label_number);
  5092. #endif
  5093.   output_asm_insn (buffer, xops);
  5094.   output_asm_insn (AS2 (mov%W0,%2,%0), xops);
  5095. #ifdef LOCAL_LABEL_PREFIX
  5096.   sprintf (buffer, \"%sLFFSHI%d:\",
  5097.        LOCAL_LABEL_PREFIX, ffshi_label_number);
  5098. #else
  5099.   sprintf (buffer, \"%sLFFSHI%d:\",
  5100.        \"\", ffshi_label_number);
  5101. #endif
  5102.   output_asm_insn (buffer, xops);
  5103.  
  5104.   ffshi_label_number++;
  5105.   return \"\";
  5106. }")
  5107.  
  5108. ;; These patterns match the binary 387 instructions for addM3, subM3,
  5109. ;; mulM3 and divM3.  There are three patterns for each of DFmode and
  5110. ;; SFmode.  The first is the normal insn, the second the same insn but
  5111. ;; with one operand a conversion, and the third the same insn but with
  5112. ;; the other operand a conversion.  The conversion may be SFmode or
  5113. ;; SImode if the target mode DFmode, but only SImode if the target mode
  5114. ;; is SFmode.
  5115.  
  5116. (define_insn ""
  5117.   [(set (match_operand:DF 0 "register_operand" "=f,f")
  5118.     (match_operator:DF 3 "binary_387_op"
  5119.             [(match_operand:DF 1 "nonimmediate_operand" "0,fm")
  5120.              (match_operand:DF 2 "nonimmediate_operand" "fm,0")]))]
  5121.   "TARGET_80387"
  5122.   "* return (char *) output_387_binary_op (insn, operands);")
  5123.  
  5124. (define_insn ""
  5125.   [(set (match_operand:DF 0 "register_operand" "=f")
  5126.     (match_operator:DF 3 "binary_387_op"
  5127.        [(float:DF (match_operand:SI 1 "general_operand" "rm"))
  5128.         (match_operand:DF 2 "general_operand" "0")]))]
  5129.   "TARGET_80387"
  5130.   "* return (char *) output_387_binary_op (insn, operands);")
  5131.  
  5132. (define_insn ""
  5133.   [(set (match_operand:XF 0 "register_operand" "=f,f")
  5134.     (match_operator:XF 3 "binary_387_op"
  5135.             [(match_operand:XF 1 "nonimmediate_operand" "0,f")
  5136.              (match_operand:XF 2 "nonimmediate_operand" "f,0")]))]
  5137.   "TARGET_80387"
  5138.   "* return (char *) output_387_binary_op (insn, operands);")
  5139.  
  5140. (define_insn ""
  5141.   [(set (match_operand:XF 0 "register_operand" "=f")
  5142.     (match_operator:XF 3 "binary_387_op"
  5143.        [(float:XF (match_operand:SI 1 "general_operand" "rm"))
  5144.         (match_operand:XF 2 "general_operand" "0")]))]
  5145.   "TARGET_80387"
  5146.   "* return (char *) output_387_binary_op (insn, operands);")
  5147.  
  5148. (define_insn ""
  5149.   [(set (match_operand:XF 0 "register_operand" "=f,f")
  5150.     (match_operator:XF 3 "binary_387_op"
  5151.        [(float_extend:XF (match_operand:SF 1 "general_operand" "fm,0"))
  5152.         (match_operand:XF 2 "general_operand" "0,f")]))]
  5153.   "TARGET_80387"
  5154.   "* return (char *) output_387_binary_op (insn, operands);")
  5155.  
  5156. (define_insn ""
  5157.   [(set (match_operand:XF 0 "register_operand" "=f")
  5158.     (match_operator:XF 3 "binary_387_op"
  5159.       [(match_operand:XF 1 "general_operand" "0")
  5160.        (float:XF (match_operand:SI 2 "general_operand" "rm"))]))]
  5161.   "TARGET_80387"
  5162.   "* return (char *) output_387_binary_op (insn, operands);")
  5163.  
  5164. (define_insn ""
  5165.   [(set (match_operand:XF 0 "register_operand" "=f,f")
  5166.     (match_operator:XF 3 "binary_387_op"
  5167.       [(match_operand:XF 1 "general_operand" "0,f")
  5168.        (float_extend:XF
  5169.         (match_operand:SF 2 "general_operand" "fm,0"))]))]
  5170.   "TARGET_80387"
  5171.   "* return (char *) output_387_binary_op (insn, operands);")
  5172.  
  5173. (define_insn ""
  5174.   [(set (match_operand:DF 0 "register_operand" "=f,f")
  5175.     (match_operator:DF 3 "binary_387_op"
  5176.        [(float_extend:DF (match_operand:SF 1 "general_operand" "fm,0"))
  5177.         (match_operand:DF 2 "general_operand" "0,f")]))]
  5178.   "TARGET_80387"
  5179.   "* return (char *) output_387_binary_op (insn, operands);")
  5180.  
  5181. (define_insn ""
  5182.   [(set (match_operand:DF 0 "register_operand" "=f")
  5183.     (match_operator:DF 3 "binary_387_op"
  5184.       [(match_operand:DF 1 "general_operand" "0")
  5185.        (float:DF (match_operand:SI 2 "general_operand" "rm"))]))]
  5186.   "TARGET_80387"
  5187.   "* return (char *) output_387_binary_op (insn, operands);")
  5188.  
  5189. (define_insn ""
  5190.   [(set (match_operand:DF 0 "register_operand" "=f,f")
  5191.     (match_operator:DF 3 "binary_387_op"
  5192.       [(match_operand:DF 1 "general_operand" "0,f")
  5193.        (float_extend:DF
  5194.         (match_operand:SF 2 "general_operand" "fm,0"))]))]
  5195.   "TARGET_80387"
  5196.   "* return (char *) output_387_binary_op (insn, operands);")
  5197.  
  5198. (define_insn ""
  5199.   [(set (match_operand:SF 0 "register_operand" "=f,f")
  5200.     (match_operator:SF 3 "binary_387_op"
  5201.             [(match_operand:SF 1 "nonimmediate_operand" "0,fm")
  5202.              (match_operand:SF 2 "nonimmediate_operand" "fm,0")]))]
  5203.   "TARGET_80387"
  5204.   "* return (char *) output_387_binary_op (insn, operands);")
  5205.  
  5206. (define_insn ""
  5207.   [(set (match_operand:SF 0 "register_operand" "=f")
  5208.     (match_operator:SF 3 "binary_387_op"
  5209.       [(float:SF (match_operand:SI 1 "general_operand" "rm"))
  5210.        (match_operand:SF 2 "general_operand" "0")]))]
  5211.   "TARGET_80387"
  5212.   "* return (char *) output_387_binary_op (insn, operands);")
  5213.  
  5214. (define_insn ""
  5215.   [(set (match_operand:SF 0 "register_operand" "=f")
  5216.     (match_operator:SF 3 "binary_387_op"
  5217.       [(match_operand:SF 1 "general_operand" "0")
  5218.        (float:SF (match_operand:SI 2 "general_operand" "rm"))]))]
  5219.   "TARGET_80387"
  5220.   "* return (char *) output_387_binary_op (insn, operands);")
  5221.  
  5222. (define_expand "strlensi"
  5223.   [(parallel [(set (match_dup 4)
  5224.            (unspec:SI [(mem:BLK (match_operand:BLK 1 "general_operand" ""))
  5225.                    (match_operand:QI 2 "register_operand" "")
  5226.                    (match_operand:SI 3 "immediate_operand" "")] 0))
  5227.           (clobber (match_dup 1))])
  5228.    (set (match_dup 5)
  5229.     (not:SI (match_dup 4)))
  5230.    (set (match_operand:SI 0 "register_operand" "")
  5231.     (minus:SI (match_dup 5)
  5232.          (const_int 1)))]
  5233.   ""
  5234.   "
  5235. {
  5236.   operands[1] = copy_to_mode_reg (SImode, XEXP (operands[1], 0));
  5237.   operands[4] = gen_reg_rtx (SImode);
  5238.   operands[5] = gen_reg_rtx (SImode);
  5239. }")
  5240.  
  5241. ;; It might seem that operands 0 & 1 could use predicate register_operand.
  5242. ;; But strength reduction might offset the MEM expression.  So we let
  5243. ;; reload put the address into %edi.
  5244.  
  5245. (define_insn ""
  5246.   [(set (match_operand:SI 0 "register_operand" "=&c")
  5247.     (unspec:SI [(mem:BLK (match_operand:SI 1 "address_operand" "D"))
  5248.             (match_operand:QI 2 "register_operand" "a")
  5249.             (match_operand:SI 3 "immediate_operand" "i")] 0))
  5250.    (clobber (match_dup 1))]
  5251.   ""
  5252.   "*
  5253. {
  5254.   rtx xops[2];
  5255.  
  5256.   xops[0] = operands[0];
  5257.   xops[1] = constm1_rtx;
  5258.   output_asm_insn (\"cld\", operands);
  5259.   output_asm_insn (AS2 (mov%L0,%1,%0), xops);
  5260.   return \"repnz\;scas%B2\";
  5261. }")
  5262.